MQTT釋出訂閱流程
在MQTT釋出/訂閱模式中,一個客戶端既可以是釋出者,也可以是訂閱者,也可以同時具備這兩個身份。當客戶端釋出一條訊息時,它會被髮送到代理,然後代理將訊息路由到該主題的所有訂閱者。當客戶端訂閱一個主題時,它會收到代理轉發到該主題的所有訊息
釋出訊息報文-Publish
客戶端連線broker後就可以釋出訊息,釋出訊息需要用Publish報文
Publish報文基礎欄位:
Topic Name-必填
欄位型別:utf-8型別的字串
欄位含義:指定釋出訊息的主題,一條訊息只能指定一個主題,如果要傳送給多個主題需要指定多條訊息
QoS-必填
- 欄位型別:int
- 欄位含義:指定訊息的服務質量等級,基礎介紹中的QoS level 1、2、3
Payload-必填
- 欄位型別:binary(二進位制)
- 欄位含義:用於指定訊息的實際內容,MQTT作為二進位制協議,payload可以是任何格式的協議,json、二進位制、密文等
Retained-選填
- 欄位型別:bool
- 欄位含義:當前訊息是否為保留訊息
Packet ID
- 唯一的標記一條訊息,QOS為1或者2的時候固定出現
- mqtt客戶端內部實現,無需我們手動實現
DUP
- 訊息是否重發標識,QoS 1&2的時候固定出現
- mqtt客戶端內部實現,無需我們手動實現
訂閱主題報文-Subscribe
訂閱主題需要使用Subscribe報文,主要包含一個Packet ID 和Subscription List(訂閱列表)
Packet ID
用來唯一標識Subscribe報文以及匹配服務端返回的SUBACK的 Packet ID,無需手動設定
Subscription List
訂閱列表可以包含多個訂閱,每個訂閱有一個topic filter和 qos組成,可以透過Subscribe報文一次性訂閱多個主題,Subscribe中主題過濾器和Publish中topic不同,可以使用萬用字元匹配多個主題
而Publish中每個訊息必須指定一個明確主題
訂閱報文中的的QoS欄位是代理向訂閱者轉發訊息時能使用的最大等級, 如果超過這個QoS等級的訊息也會轉發,如果傳送這種情況,訊息也會轉發,但是QoS會降級,比如訂閱的時候請求的等級為1,釋出者如果釋出的為2等級,代理轉發的時候會降級為1,如果釋出者釋出0或者1,因為沒有超過請求者最大的QoS,會保持不變,相當於訊息轉發時候的QoS等級永遠是訊息釋出時的QoS等級和訂閱時候服務端授予的QoS等級這兩者的最小值
訂閱邏輯
訂閱的時候同一個客戶端使用相同主題的過濾器多次訂閱時,新的訂閱將覆蓋舊的訂閱,不會出現訂閱失敗和收到重複的訊息,如果同一個客戶端使用不同的主題過濾器進行訂閱,不同的主題過濾器匹配到同一個主題時,每個訂閱都將收到一次訊息
訂閱可能會失敗,比如不具備主題的訪問許可權或者拒絕訂閱,broker會返回SUBACK報文返回訂閱的結果,SUBACK報文中包含Subscribe報文一致的Packet ID,以及和訂閱列表一一對應的Reason Codes
Reason Codes
訂閱結果的原因碼
0x00-訂閱成功且最大QoS等級為0
0x01-訂閱成功且最大QoS等級為1
0x02-訂閱成功且最大QoS等級為2
0x80-訂閱失敗
取消訂閱報文-Unsubscribe
取消訂閱報文與訂閱報文型別,包含一個Packet ID 和一個期望取消的主題過濾器列表,想要取消的Topic filter 需要與實際訂閱的 Topic filter完全的文字匹配
Unsubscribe報文同樣也有UNSUBACK報文進行響應,但是在MQTT 3.1.1沒有Reason Codes原因碼確認是否成功, 在MQTT 5.0裡面進行補充,有對應Reason Codes