MQTT-釋出與訂閱的報文

秀兒y發表於2023-04-21
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不同,可以使用萬用字元匹配多個主題image-20230421164020053

    而Publish中每個訊息必須指定一個明確主題

    image-20230421164105024

    訂閱報文中的的QoS欄位是代理向訂閱者轉發訊息時能使用的最大等級, 如果超過這個QoS等級的訊息也會轉發,如果傳送這種情況,訊息也會轉發,但是QoS會降級,比如訂閱的時候請求的等級為1,釋出者如果釋出的為2等級,代理轉發的時候會降級為1,如果釋出者釋出0或者1,因為沒有超過請求者最大的QoS,會保持不變,相當於訊息轉發時候的QoS等級永遠是訊息釋出時的QoS等級和訂閱時候服務端授予的QoS等級這兩者的最小值

  • 訂閱邏輯

訂閱的時候同一個客戶端使用相同主題的過濾器多次訂閱時,新的訂閱將覆蓋舊的訂閱,不會出現訂閱失敗和收到重複的訊息,如果同一個客戶端使用不同的主題過濾器進行訂閱,不同的主題過濾器匹配到同一個主題時,每個訂閱都將收到一次訊息

image-20230421165634156

訂閱可能會失敗,比如不具備主題的訪問許可權或者拒絕訂閱,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完全的文字匹配image-20230421170525806

Unsubscribe報文同樣也有UNSUBACK報文進行響應,但是在MQTT 3.1.1沒有Reason Codes原因碼確認是否成功, 在MQTT 5.0裡面進行補充,有對應Reason Codes

相關文章