樹莓派安裝 Mosquitto 輕量級 MQTT Broker 教學,連接各種物聯網設備

Mosquitto 是一個開放原始碼 MQTT broker,安裝於樹莓派中就可以把所有的感測器、運算與控制設備連結起來,打造一個整合性的物聯網架構。

在物聯網的應用中,有許多的感測器會產生各種的資料,這些資料可能會傳送至資料庫中儲存、交給運算伺服器分析、或是直接傳遞至使用者端即時顯示,而物聯網中的各種設備也需要接收來自於使用者或自動控制程式程式的指令,進行各種智慧化的動作,要讓整個物聯網環境具備互相溝通的能力,就需要有一個資訊傳遞的機制。


MQTT 是一種 machine-to-machine(M2M) 的輕量級通訊協定,可以讓各種設備互相溝通,而其所需要的運算與傳輸頻寬很低,非常適合用於物聯網中的各種應用。

在 MQTT 的通訊架構之下,會有一台設備專門負責所有訊息的派送工作,這個角色就稱為 broker,所有的訊息在傳遞時都會經過 broker,由 broker 來負責處理每一則訊息該如何遞送。

MQTT 通訊協定與物聯網 IOT 應用整合概念

MQTT broker 的實作有非常多種,例如 ActiveMQ ApolloHiveMQMoscaMosquittoRabbitMQ 等,基本上來說不管使用那一個實作版本都可以,功能上不會差太多。

這裡我們以樹莓派的 Linux 環境為例,介紹 Mosquitto 這一個 MQTT 實作版本的安裝與使用方式,也就是把樹莓派打造成一個 MQTT broker 的角色,負責所有物聯網設備之間的相互溝通。

名稱:Mosquitto
描述:開放原始碼 MQTT Broker
網址:Mosquitto 官方網站

安裝 Mosquitto

在樹莓派的 Raspbian Linux 中我們可以使用 apt 直接安裝 mosquitto 套件,同時也順便安裝 mosquitto-clients 這個 MQTT clients 的套件,方便測試:

apt-get install mosquitto mosquitto-clients

正常來說,安裝完成後 mosquitto 服務會自動啟動,我們可以使用 service 指令檢查一下 mosquitto 服務的狀態:

service mosquitto status

mosquitto 服務狀態

服務的狀態呈現綠色的 active 就表示 Mosquitto 有在正常運作,接著就可以開始使用 MQTT Broker 的功能了。

使用 Mosquitto MQTT Broker

在 MQTT 的架構中,設備可分為三種:

  • Publisher:發送訊息者。
  • Subscriber:接收訊息者。
  • Broker:轉送訊息者。

而不同的訊息可能會需要傳遞給不同的接收者,所以訊息在發送的時候,發送者(publisher)必須標示這則訊息的主題(topic),而轉送訊息者(broker)則會依照這則訊息的主題,將訊息傳遞給有訂閱該主題的接收者(subscriber),這就是 MQTT 基本的訊息傳遞架構。

MQTT 訊息傳遞架構

在物聯網的應用中,一個設備可以是訊息的接收者,接收從其他設備發送過來的訊息,同時也可以訊息的發布者,發送訊息給其他設備。

了解這個 MQTT 的基本架構之後,我們可以開啟一個虛擬終端機視窗,使用 mosquitto_sub 指令來訂閱指定的主題,也就是成為一個訊息的接收者:

mosquitto_sub -t gtwang/test

這裡的 -t 參數就是指定要訂閱的主題(topic),而後面的 gtwang/test 就是主題的名稱。

MQTT 的主題在使用時不需要事先設定,直接在發布或訂閱時指定自己要的主題名稱即可。

MQTT 中的主題名稱類似一般的檔案系統,是採用階層的方式命名,我們可以自己決定命名的規則,要使用幾層都可以,善用有條理的命名方式可以讓訊息更好管理,例如 sensors/COMPUTER_NAME/temperature/HARDDRIVE_NAME 這樣就是一個不錯的命名方式。

接著再開啟另外一個虛擬終端機視窗,作為訊息的發送者,使用 mosquitto_pub 將訊息發送至 gtwang/test 這個主題:

mosquitto_pub -t gtwang/test -m "Hello, world!"

這裡的 -m 參數就是指定要送出的訊息內容,執行這行指令之後,就會將訊息傳送至 broker,在由 broker 將訊息送給 gtwang/test 主題的訂閱者,也就是另外一個虛擬終端機視窗,所以這時候就可以在另外一個視窗中看到這行訊息。

Mosquitto client

以上就是基本 MQTT 訊息傳遞的傳送方式。

訂閱多個主題

MQTT 的主題設計成階層式的架構,主要是為了可以支援比較複雜的訂閱規則,最簡單的主題訂閱方式就是直接指定完整的主題名稱,例如:

sensors/my_computer/temperature/my_hd

除了這種方式之外,我們可以利用加號 + 這個萬用字元來匹配任意的名稱,例如:

sensors/+/temperature/+

這樣的話就會接收到所有第一層為 sensors 而第三層為 temperature 的訊息。

假設有一個主題名稱為 a/b/c/d,則以下這幾種主題指定方式都可以匹配該主題:

  • a/b/c/d
  • +/b/c/d
  • a/+/c/d
  • a/+/+/d
  • +/+/+/+

但是以下這幾種就不會與 a/b/c/d 批配:

  • a/b/c
  • b/+/c/d
  • +/+/+

另外一種萬用字元是井字號 #,這個萬用字元專門用於結尾處,可以匹配之後所有的階層,以下幾種寫法都可以匹配 a/b/c/d

  • #
  • a/#
  • a/b/#
  • a/b/c/#
  • +/b/c/#

使用者認證

預設的 Mosquitto 服務是允許匿名登入使用的,也就是說任何人都可以透過 MQTT 的協定傳送與接收資料,若是在封閉的網路環境之下是沒有問題,但若是開放性的網路,最好就要上一些安全機制。

最基本的安全機制就是設定登入的帳號密碼,只有經過認證的使用者可以透過 Mosquitto 服務傳送或是接收資料,以下是 Mosquitto 設定帳號與密碼的步驟。

Step 1
建立 Mosquitto 用的帳號密碼檔案,並新增 gtwang 這個使用者:

mosquitto_passwd -c /etc/mosquitto/passwd gtwang

執行這行指令後,接著要設定 gtwang 的密碼。

Step 2
編輯 /etc/mosquitto/mosquitto.conf 設定檔,加入以下設定:

# 設定帳號密碼檔案
password_file /etc/mosquitto/passwd

# 禁止匿名登入
allow_anonymous false

Step 3
重新啟動 mosquitto 服務:

service mosquitto restart

Step 4
以設定好的帳號密碼登入,訂閱 gtwang/test 主題:

mosquitto_sub -t gtwang/test -u gtwang -P secret123

以設定好的帳號密碼登入,發送訊息至 gtwang/test 主題:

mosquitto_pub -t gtwang/test -u gtwang -P secret123 -m "Hello, world!"

設定好使用者認證機制之後,接下來還要設定安全加密連線,請繼續閱讀下一頁。

樹莓派, 物聯網

3 Comments

  1. df

    安全加密 TLS 連線:
    STEP5步驟:出現以下訊息
    Error: Problem setting TLS options.

  2. Jennifer

    可否請教一下 我在安裝時出現以下情況 Err http://mirrordirector.raspbian.org/raspbian/ jessie/main mosquitto armhf 1.3.4-2+deb8u1
    Could not resolve ‘mirrordirector.raspbian.org’
    E: Failed to fetch http://mirrordirector.raspbian.org/raspbian/pool/main/m/mosquitto/mosquitto_1.3.4-2+deb8u1_armhf.deb Could not resolve ‘mirrordirector.raspbian.org’

    E: Unable to fetch some archives, maybe run apt-get update or try with –fix-missing?
    root@ittraining:~# apt-get update
    Err http://archive.raspberrypi.org jessie InRelease

    Err http://mirrordirector.raspbian.org jessie InRelease

    Err http://archive.raspberrypi.org jessie Release.gpg
    Could not resolve ‘archive.raspberrypi.org’
    Err http://mirrordirector.raspbian.org jessie Release.gpg
    Could not resolve ‘mirrordirector.raspbian.org’
    Reading package lists… Done
    W: Failed to fetch http://mirrordirector.raspbian.org/raspbian/dists/jessie/InRelease

    W: Failed to fetch http://archive.raspberrypi.org/debian/dists/jessie/InRelease

    W: Failed to fetch http://archive.raspberrypi.org/debian/dists/jessie/Release.gpg Could not resolve ‘archive.raspberrypi.org’

    W: Failed to fetch http://mirrordirector.raspbian.org/raspbian/dists/jessie/Release.gpg Could not resolve ‘mirrordirector.raspbian.org’

    W: Some index files failed to download. They have been ignored, or old ones used instead.

Leave a Reply