MQTT協議是一個簡單的中心輻射型系統:感測器、應用和裝置之間的通訊是透過中央代理端執行的資料中心服務實現的。其精簡低頻寬的特性使得它能夠適用於很多應用,比如家庭自動化:包括供暖、通風、空調(HVAC)、照明、智慧裝置和安全等方面都採用了MQTT協議。
1、淺談歷史
MQTT協議由Andy Stanford-Clark(IBM)和Arlen Nipper(Arcom,現為Cirrus Link)於1999年發明。他們需要一種協議,以最小化電池損耗和最小頻寬,透過衛星與石油管道連線。 發明之初為協議規定了幾個要求:
- 實施簡單
- 提供服務質量的資料傳輸
- 輕巧和頻寬高效
- 資料不可知
- 持續的會話意識
2、協議格式
MQTT協議控制報文的格式包含以下三個部分,以固定報頭,可變報頭和有效載荷,其中固定報文頭是所有的控制報文都有, 可變報頭和有效載荷都是部分控制報文包含。
固定報頭
固定報頭是兩個位元組組成,其具體的格式如下所示:
控制報文型別
第一個位元組的二進位制位7-4無符號整數表示控制報文的型別,具體型別對應的值為:
備註: 其中預留值15已經在MQTT5中使用到AUTH中了。
標誌
第一個位元組的二進位制位3-0包含每個MQTT控制報文型別特定的標誌, 控制報文中的標誌為必須按照如下表格進行設定,如果設定有問題,則接收者必須斷開連線。
備註:從協議規範看出,目前只有PUBLISH的標誌位是使用的,其他控制報文都是預留狀態,但是必須保持上述表格的形式。
剩餘長度
第二個位元組表示當前報文剩餘部分的位元組數,包括可變報頭和有效載荷。剩餘長度不包括用於編碼剩餘長度欄位本身的位元組數。剩餘長度欄位使用一個變長度編碼方案,對小於128的值使用單位元組編碼,超過128的值,最高有效未用於指示是否有更多的位元組,因此每個位元組可以編碼128個數值和一個延續位,剩餘長度欄位最大4個位元組。 舉例:十進位制64被編碼為一個位元組,十六進製表示為Ox40。十進位制數字321編碼為兩個位元組,最低有效位在前,第一個位元組65+128=193,第二個位元組為2。 剩餘長度最大為256M的報文,而且報文是不支援分包處理的,所以MQTT協議並不適合一些資料量特別大的場景,比如影片直播等資料包比較大的場景。
可變報頭
可變報頭介於固定報頭和有效載荷中間。不同的控制報文有著不同的可變報頭,其中PacketId是一個在多個控制報文中存在一個報文。 PacketId包含兩個位元組,現在包含該欄位的控制報文有,PUBLISH(Qos>0), PUBACK, PUBREC, PUBREL,PUBCOMP,SUBSCRIBE,SUBACK, UNSUBSCRIBE, UNSUBACK。
具體包含情況如下:
註意事項
- PUBLISH Qos0的報文是不能又packetId的。
- 有些對應的控制報文中的packetId必須和與該控制報文系結的其它控制報文保持一直,例如PUBLISH Qos1對應的是PUBACK,PUBLISH Qos2對應的PUBCOMP。
- 傳送者和接收者是分開維護各自的packetId,所以會出現互動雙方出現相同packetId的兩個不同的控制報文。
- 關於不能有packetId的控制報文,可能是由於packetId是可以復用的,沒有辦法確認可以復用的場景不能使用報文,比如Qos0的PUBLISH報文,由於沒有回應,所以傳送者無法得知packetId何時可以釋放復用,故不允許存在該欄位。
有效載荷
有效載荷即為應用訊息。 目前MQTT3.1.1中包含如下的控制報文CONNECT, CONNACK, PUBLISH, PUBACK,PUBREC, PUBREL, PUBCOMP,SUBSCRIBE,SUBACK,UNSUBSCRIBE,UNSUBACK,PINGREQ,PINGRESP,DISCONNECT的協議,關於這些協議的具體格式,使用場景等將在後續的文章中給出解釋。
總結
MQTT是二進位制的協議,控制欄位是精確到Bit級別的,單純這一點就足以為其在物聯網領域佔據一席之地。MQTT是不支援分包等機制,並不適宜一些資料包特別大的應用場景。