MQTT v5 (MQTT 5.0) 新特性介紹

MQTT v5 (MQTT 5.0) 新特性介紹

項目中逐步完成了 MQTT 5.0的開發,這裏介紹下MQTT 5.0 的一些新特性
MQTT 5.0 規範見:http://docs.oasis-open.org/mqtt/mqtt/v5.0/cos01/mqtt-v5.0-cos01.html#_Toc514847900

格式

首先,協議上,增加了一個 Property字段,正是這個字段,使得 MQTT 5.0 可以支持衆多的新特性。而在MQTT 3.1.1中,MQTT沒有任何可以拓展的地方,限制了MQTT拓展功能的可能性。

request/response 模式

MQTT 本身是 訂閱/推送 模式,不像HTTP那樣 請求/響應 模式。那麼MQTT是如何在 訂閱/推送 模式下支持 request/response 模式呢?
這裏簡單翻譯了 http://docs.oasis-open.org/mqtt/mqtt/v5.0/cos01/mqtt-v5.0-cos01.html#_Request_/_Response 中舉例的場景:

(1)A publish 一個消息,消息topic假設是"topicA",該消息 通過Property攜帶了Response Topic,假設該字段是"topicresponse"。
(2)訂閱了"topicA"的接收端B(有可能有多個)收到了該消息。
(3)B處理完"topicA"後,會publish 一個 topic 名字是 “topicresponse” 的消息。該消息有可能是A訂閱的,也有可能是其他人訂閱的。
(4)A publish 的消息,可能還會攜帶Correlation Data屬性,假設其值是"msgresponse",這樣B發publish的消息就是(“topicresponse”, “msgresponse”)。

Server redirection

Server可以發送 CONNACK 或者 DISCONNECT,其 Reason Codes 可以是0x9c或者0x9d,表示Client需要往另一個Server發送請求。
0x9C 類似 HTTP 的 302, 0x9d 類似 HTTP的 301。
CONNACK 或者 DISCONNECT 可以通過 Property攜帶Server redirection,其值可以告訴Client往哪個Server發送請求,類似HTTP的"Location"首部。

AUTH控制報文

MQTT 單純通過 CONNECT可能無法提供足夠的信息給Server進行身份認證,所以 Server 在收到 MQTT 的 CONNECT 後,回覆 AUTH控制報文給Client,Client接着也用 AUTH包發送附加信息,Server直到 認證完成後,纔會發送 CONNACK

Topic Alias

類似HTTP2的頭部壓縮效果,當然,沒有同HPACK那麼複雜的東西。

我們知道,PUBLISH消息的時候,需要攜帶 topic和message,其中topic往往是固定的,那麼我們只需要第一次發送完整的 topic,並且通過Property中攜帶Topic Alias告知對端下次這個PUBLISH的topic會使用Topic Alias中的值代替,Topic Alias的值是一個整數類型的值。

client 通過 CONNECTTopic Alias Maximum 告知 Server自己能處理的最多的 Topic Alias 個數。
Server 通過 CONNACKTopic Alias Maximum 告知 Client自己能處理的最多的 Topic Alias 個數。

如果當前PUBLISH消息的topic長度不爲0,那麼接受方需要解析 Topic Alias 中的值,並且 將topic和該值進行映射。
如果當前PUBLISH消息的topic爲0,那麼接受方需要解析 Topic Alias 中的值,用該值去查找對應的topic。

User Property

自定義屬性,可以添加兩端約定的數據。例如可以加入類似HTTP的 "Header:value"信息。MQTT本身沒有類似HTTP的HOST信息,我們可以使用User Property特性讓MQTT支持。

Session Expiry Interval

之前的MQTT版本,當cleansession爲0時,server和client會嘗試保存session信息(sub信息、PUBLISH狀態等),但是有個問題,server 不知道需要保存這個session多久。MQTT 5.0 就 在 Property字段中增加了Session Expiry Interval屬性來告知server這個session希望被保存多久。

如果MQTT 5.0 不攜帶 Session Expiry Interval或者 Session Expiry Interval設置爲0,server和client則不會保存session信息。
如果Session Expiry Interval設置爲0xffffffff,則表示session永遠不會老化。

當然,這個字段是需要配合Clean Start使用的,如果Clean Start爲1,那麼 Session Expiry Interval設置多大都無意義。

CONNECT、CONNACK、DISCONNECT都會發送 Session Expiry Interval字段。DISCONNECT中攜帶該字段可以告知Server更新老化時間。
CONNACK中的Session Expiry Interval只有當CONNECT不攜帶該字段時纔有用,當client攜帶該字段,server發送該字段只是表明自己最大的老化時間,不會強制client必須按照這個值。

Maximum QoS

Server 可以發送 Maximum QoS屬性告知Client自己支持最大的Qos是多少,Client發送的PUBLISH的Qos必然不能大於該值。

Receive Maximum

告知對方自己希望處理未決的最大的 Qos1 或者 Qos2 PUBLISH消息個數,如果不存在,則默認是65535。
作用:流控。
因爲當處理 Qos > 0 的PUBLISH的時候,需要回復對端PUBACK、PUBREC PUBCOMP等。Receive Maximum屬性提供了告訴對端發送Qos>0的PUBLISH的速率,對端發現未決PUBLISH個數等於Receive Maximum時,不能再發送Qos > 0 的PUBLISH消息了。

Maximum Packet Size

顧名思義,單個 MQTT控制報文 的大小,如果不攜帶,表示不限制。
這個大小指整個 MQTT控制報文 的大小。對端如果發現將發送的包大於該大小,就默默丟棄,不關閉連接。如果自己收到超過自己通告的Maximum Packet Size需要關閉連接。

Topic Alias Maximum

作用見上文Topic Alias

Reason Code

MQTT 3.1.1 只有CONNACK有是否成功還是失敗的標誌位,現在MQTT 5.0所有的ACK都有該標誌位。具體各個ACK中code值得含義在規範中有定義,這裏不再列舉。
需要注意的是,SUBACK中,MQTT 3.1.1 的 Granted Qos被取代爲Reason CodeReason Code中有狀態碼錶示了具體的Granted Qos
如果PUBLISH是成功的,其ACK的的Reason Code可以不添加。

Reason String

所有的ACK以及DISCONNECT 都可以攜帶 Reason String屬性告知對方一些特殊的信息,一般來說是ACK失敗的情況下會使用該屬性告知對端爲什麼失敗,可用來彌補Reason Code信息不夠。

Clean Start

Clean Start取代了 MQTT3.1.1 中 CleanSession,在協議格式上,直接佔用了CleanSession原本的field,這也表示Clean Start語義上和 CleanSession是一樣的。

Payload Format Indicator

指定了PUBLISH 消息的message部分是utf8格式的還是二進制的,接收方必須驗證payload是否是該屬性定義的格式。
Payload Format Indicator 爲 0,表示 是二進制,和不攜帶該屬性的語義是一樣的。
Payload Format Indicator 爲 1,表示 是utf8編碼數據。

Message Expiry Interval

指定了PUBLISH數據在Server的最長等待時間。超過這個時間,這個數據不能被publish到匹配topic的subscriber

還有其他的細枝末節不再展開了,上述衆多屬性也有一些細節的地方,可以在原文中搜索就直到了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章