現在我們來快速體驗一下,使用MQTT進行資料的釋出和訂閱。
考慮到Mosquitto比較適合初學者,所以選擇它來做實驗。實驗環境是Windows 10 64 bit,Mosquitto版本是1.5.8。
Mosquitto安裝
- 進入Mosquitto下載頁面,選擇對應的作業系統下載安裝。Windows使用者下載安裝包,一直點選下一步到安裝結束,系統預設會安裝到"C:\Program Files\mosquitto",為方便使用,將這個路徑加到Path環境變數中。安裝成功後,會新增一個叫Mosquitto Broker的系統服務,並且會自動啟動。
- 這裡順便講一下,如果是CentOS使用者,可以直接使用yum install mosquitto命令進行安裝的。其它平臺的安裝參見下載頁,有詳細說明。
- 使用windows + r,執行命令services.msc,開啟windows服務,找到Mosquitto Broker服務,檢視服務狀態,如果服務沒啟動,則啟動服務。現在就可以連線到Broker了。
訂閱主題
開啟命令列終端,輸入如下命令訂閱主題topic1。
$ mosquitto_sub -d -t topic1
Client mosqsub|3508-SCNWCL0121 sending CONNECT
Client mosqsub|3508-SCNWCL0121 received CONNACK (0)
Client mosqsub|3508-SCNWCL0121 sending SUBSCRIBE (Mid: 1, Topic: topic1, QoS: 0)
Client mosqsub|3508-SCNWCL0121 received SUBACK
Subscribed (mid: 1): 0
複製程式碼
以上第一行是命令,使用mosquitto_sub命令訂閱主題。
-d 參數列示啟用debug模式,這樣mosquitto_sub會顯示詳細的連線以及資料收發過程。
-t topic1 表示需要訂閱主題topic1。
這裡有些引數沒寫,都使用了預設值,如host使用了localhost,port使用了1883,並且使用了"mosqsub|3508-SCNWCL0121"作為Client ID,其中3508是程式Id,SCNWCL0121是我的機器名。
如果要指定host,port以及Client Id,可以這樣使用。
$ mosquitto_sub -d -h localhost -p 1883 -i subscriber-test -t topic1
Client subscriber-test sending CONNECT
Client subscriber-test received CONNACK (0)
Client subscriber-test sending SUBSCRIBE (Mid: 1, Topic: topic1, QoS: 0)
Client subscriber-test received SUBACK
Subscribed (mid: 1): 0
複製程式碼
-h 表示host
-p 表示port
-i 表示客戶端ID。
其實所有的命令列使用都可以使用--help進行查閱,輸入
$ mosquitto_sub --help
你就會看到它的詳細用法,所有引數都顯示出來了,很詳細。
第二行和第三行是建立連線的過程。
Client mosqsub|3508-SCNWCL0121 sending CONNECT
Client mosqsub|3508-SCNWCL0121 received CONNACK (0)
複製程式碼
表示客戶端“mosqsub|3508-SCNWCL0121”傳送CONNECT,同時Broker回覆CONNACK (0)。其中0是狀態碼,表示連線成功。如果是其它數字,則表示連線失敗。失敗的原因有很多,比如不支援當前協議,伺服器不可用等等,具體可參見Connect Return Code。
第四行到第六行是訂閱主題的過程,
Client mosqsub|3508-SCNWCL0121 sending SUBSCRIBE (Mid: 1, Topic: topic1, QoS: 0)
Client mosqsub|3508-SCNWCL0121 received SUBACK
Subscribed (mid: 1): 0
複製程式碼
sending SUBSCRIBE (Mid: 1, Topic: topic1, QoS: 0)表示傳送訂閱請求,
Mid是Message Id,從1開始計算,當一個連線傳送多條訊息時,Mid是遞增的。
Topic:topic1表示要訂閱的主題時topic1。
QoS:0指定了QoS等級,預設是0。
釋出訊息
開啟一個新的命令列終端,輸入以下命令
$ mosquitto_pub -d -t topic1 -m "Hello MQTT"
Client mosqpub|12796-SCNWCL012 sending CONNECT
Client mosqpub|12796-SCNWCL012 received CONNACK (0)
Client mosqpub|12796-SCNWCL012 sending PUBLISH (d0, q0, r0, m1, 'topic1', ... (10 bytes))
Client mosqpub|12796-SCNWCL012 sending DISCONNECT
複製程式碼
第一行是釋出訊息命令,將訊息釋出到主題topic1,-m 指定了傳送訊息的內容是"Hello MQTT"。我們同樣啟用了debug模式。
第二行和第三行是連線過程
第四行是釋出的訊息資訊。
Client mosqpub|12796-SCNWCL012 sending PUBLISH (d0, q0, r0, m1, 'topic1', ... (10 bytes))
複製程式碼
其中d0, q0, r0, m1,分別是釋出訊息指定的引數,這裡使用預設引數。
d0表示DUP為0,DUP是是否重複標記,如果是第一次傳送訊息,則設定為0。如果是重複投遞,比如QoS設定為1,客戶端傳送訊息超時後伺服器還沒有回覆,客戶端為確保訊息能發出去,於是再發一次,這是DUP就設定為1,表明這個訊息是重複傳送的。
q0表示QoS為0。
r0表示RETAIN為0。RETAIN意思是是否要求Broker幫我保留這條訊息,如果設定為1,則伺服器會保留當前訊息。當下一次有新的客戶端連線並訂閱topic1時,伺服器自動傳送這條保留的訊息給客戶端。
m1表示訊息序號,預設從1開始。
topic1是釋出到這個主題。
... (10 bytes)沒有顯示訊息內容,但是顯示了訊息長度是10個位元組。
最後一行是斷開連線。
Client mosqpub|12796-SCNWCL012 sending DISCONNECT
接收訊息
釋出完訊息後,再回到之前訂閱的終端,會顯示接收到的訊息。
Client mosqsub|11104-SCNWCL012 received PUBLISH (d0, q0, r0, m0, 'topic1', ... (10 bytes))
topic1 Hello MQTT
複製程式碼
第一行顯示收到PUBLISH資料包,第二行列印出接收到的資料。
總結
Mosquitto是很容易使用的MQTT實現,包含了服務端和客戶端。在這個實驗中,我們其實就執行了兩條命令。
$ mosquitto_sub -d -t topic1
$ mosquitto_pub -d -t topic1 -m "Hello MQTT"
複製程式碼
分別表示訂閱主題和釋出訊息,當另一個客戶端傳送訊息成功後,訂閱端會收到訊息並列印出來。
在以上命令中,-d引數非常有用,是我們學習MQTT協議的利器,這裡舉個列子。
QoS是服務質量保證,在釋出訊息時,當QoS設定為0,那麼客戶端傳送訊息後,Broker是不做回覆的。
QoS設定為1時,客戶端傳送訊息後,會等待Broker確認,如果等不到PUBACK,那麼過一段時間後會重新傳送。這樣確保Broker能收到訊息。我們來對比一下。
$ mosquitto_pub -d -t topic1 -m "Hello MQTT"
Client mosqpub|6188-SCNWCL0121 sending CONNECT
Client mosqpub|6188-SCNWCL0121 received CONNACK (0)
Client mosqpub|6188-SCNWCL0121 sending PUBLISH (d0, q0, r0, m1, 'topic1', ... (10 bytes))
Client mosqpub|6188-SCNWCL0121 sending DISCONNECT
複製程式碼
$ mosquitto_pub -d -q 1 -t topic1 -m "Hello MQTT"
Client mosqpub|14788-SCNWCL012 sending CONNECT
Client mosqpub|14788-SCNWCL012 received CONNACK (0)
Client mosqpub|14788-SCNWCL012 sending PUBLISH (d0, q1, r0, m1, 'topic1', ... (10 bytes))
Client mosqpub|14788-SCNWCL012 received PUBACK (Mid: 1)
Client mosqpub|14788-SCNWCL012 sending DISCONNECT
複製程式碼
當我們傳送訊息時,如果增加引數-q 1,表示QoS設定成1。資料包就會多出一個回覆。
Client mosqpub|14788-SCNWCL012 received PUBACK (Mid: 1)
QoS的實現機制比較複雜,後續我會專門寫一篇文章講MQTT QoS,有興趣的可以自己點選連結先去看看。