一、協(xié)議概述
物聯(lián)網(wǎng)(Internet of Things,IoT)最近曝光率越來越高昂羡。雖然HTTP是網(wǎng)頁的事實標(biāo)準(zhǔn)待笑,不過機(jī)器之間(Machine-to-Machine鸣皂,M2M)的大規(guī)模溝通需要不同的模式:之前的請求/回答(Request/Response)模式不再合適,取而代之的是發(fā)布/訂閱(Publish/Subscribe)模式暮蹂。這就是輕量級寞缝、可擴(kuò)展的MQTT(Message Queuing Telemetry Transport)可以施展拳腳的舞臺。
MQTT是基于二進(jìn)制消息的發(fā)布/訂閱編程模式的消息協(xié)議仰泻,最早由IBM提出的荆陆,如今已經(jīng)成為OASIS規(guī)范。由于規(guī)范很簡單集侯,非常適合需要低功耗和網(wǎng)絡(luò)帶寬有限的IoT場景被啼,比如:遙感數(shù)據(jù)、汽車棠枉、智能家居浓体、智慧城市、醫(yī)療醫(yī)護(hù)辈讶。
由于物聯(lián)網(wǎng)的環(huán)境是非常特別的命浴,所以MQTT遵循以下設(shè)計原則:
--精簡,不添加可有可無的功能。
--發(fā)布/訂閱(Pub/Sub)模式生闲,方便消息在傳感器之間傳遞媳溺。
--允許用戶動態(tài)創(chuàng)建主題,零運(yùn)維成本跪腹。
--把傳輸量降到最低以提高傳輸效率褂删。
--把低帶寬、高延遲冲茸、不穩(wěn)定的網(wǎng)絡(luò)等因素考慮在內(nèi)屯阀。
--支持連續(xù)的會話控制。
--理解客戶端計算能力可能很低轴术。
--提供服務(wù)質(zhì)量管理难衰。
--假設(shè)數(shù)據(jù)不可知,不強(qiáng)求傳輸數(shù)據(jù)的類型與格式逗栽,保持靈活性盖袭。
運(yùn)用MQTT協(xié)議,設(shè)備可以很方便地連接到物聯(lián)網(wǎng)云服務(wù)彼宠,管理設(shè)備并處理數(shù)據(jù)鳄虱,最后應(yīng)用到各種業(yè)務(wù)場景,如下圖所示:
二凭峡、協(xié)議詳解
整個協(xié)議的構(gòu)造拙已,從整體上協(xié)議可拆分為: ? 固定頭部+可變頭部+消息體
1、固定頭部(fixed header):
構(gòu)造如下:
? ?? 1)Message Type(0和15保留摧冀,共占4個字節(jié))
2)DUP flag:其是用來在保證消息傳輸可靠的倍踪,如果設(shè)置為1,則在下面的變長頭部里多加MessageId,并需要回復(fù)確認(rèn)索昂,保證消息傳輸完成建车,但不能用于檢測消息重復(fù)發(fā)送。
3)QoS level:主要用于PUBLISH(發(fā)布態(tài))消息的椒惨,保證消息傳遞的次數(shù)缤至。
00表示最多一次 即<=1
01表示至少一次 ?即>=1
10表示一次,即==1
11保留后用
4)RETAIN:主要用于PUBLISH(發(fā)布態(tài))的消息康谆,表示服務(wù)器要保留這次推送的信息凄杯,如果有新的訂閱者出現(xiàn),就把這消息推送給它秉宿。如果不設(shè)那么推送至當(dāng)前訂閱的就釋放了戒突。
5)固定頭部的byte 2:是用來保存接下去的變長頭部+消息體的總大小的。但并不是直接保存的描睦,同樣也是可以擴(kuò)展的膊存,其機(jī)制是,前7位用于保存長度,后一位用做標(biāo)識隔崎。
舉個例子:即如果計算出后面的大小為 0<length<=127,正常保存今艺;如果是127<length<16383,則需要二個字節(jié)保存了,將第一個字節(jié)的最大的一位置1,表示未完爵卒。然后第二個字節(jié)繼續(xù)存虚缎。拿130來說,第一個字節(jié)存10000011,第二個字節(jié)存000000001钓株,也就是0x83,0x01,把兩個字節(jié)連起來看实牡,第二個字節(jié)權(quán)重從2的8次開始。同起可以加第3個字節(jié)轴合,最多可以加至第4個字節(jié)创坞。故MQTT協(xié)議最多可以實現(xiàn)268?435?455 (0xFF, 0xFF, 0xFF, 0x7F)將近256M的數(shù)據(jù)∈芨穑可謂能伸能縮题涨。
例如,數(shù)字64十進(jìn)制被編碼為單個字節(jié)总滩,十進(jìn)制值64纲堵,十六進(jìn)制0x40。數(shù)字321十進(jìn)制(= 65 + 2 * 128)被編碼為兩個字節(jié)闰渔,最不重要席函。第一個字節(jié)65 + 128 = 193。請注意澜建,頂部位被設(shè)置為至少指示一個后續(xù)字節(jié)。第二個字節(jié)是2蝌以。
2炕舵、可變頭部(variable header):
整體結(jié)構(gòu)為:
1)首先最上面的8個字節(jié)是Protocol Name(協(xié)議名稱),UTF編碼的字符“MQIsdp”跟畅,頭兩個是編碼名提長為6咽筋。這里多說 ?? 一些,接下去的協(xié)議多采用這種方式組合徊件,即頭兩個字節(jié)表示下一部分的長奸攻,然后后面跟上內(nèi)容。這里頭兩個字節(jié)長 ?? 為6虱痕,下面跟6個字符“MQIsdp”睹耐。
2)Protocol Version,協(xié)議版本號部翘,v3 也是固定的硝训。
3)Connect Flag,連接標(biāo)識,有點像固定頭部的窖梁。8位分別代表不同的標(biāo)志赘风。第1個字節(jié)保留。
? ? Clean Session,Will flag纵刘,Will Qos, Will Retain都是相對于CONNECT消息來說的邀窃。
?? Clean Session:0表示如果訂閱的客戶機(jī)斷線了,那么要保存其要推送的消息假哎,如果其重新連接時瞬捕,則將這些消息推 ? ? ?? 送。1表示消除位谋,表示客戶機(jī)是第一次連接山析,消息所以以前的連接信息。
? Will Flag掏父,表示如果客戶機(jī)在不是在發(fā)送DISCONNECT消息中斷笋轨,比如IO錯誤等,將些置為1,要求重傳赊淑。并且下面的 ? ? Will Qos和Will Retain也要設(shè)置爵政,消息體中的Topic和MessageID也要設(shè)置,就是表示發(fā)生了錯誤陶缺,要重傳钾挟。
? Will Qos,在CONNECT非正常情況下設(shè)置饱岸,一般如果標(biāo)識了Will Flag掺出,那么這個位置也要標(biāo)識。
?? Will RETAIN:同樣在CONNECT中苫费,如果標(biāo)識了Will Flag,那么些位也一定要標(biāo)識汤锨。
? usename flag和password flag,用來標(biāo)識是否在消息體中傳遞用戶和密碼百框,只有標(biāo)識了闲礼,消息體中的用戶名和密碼才 ? ?? 用效,只標(biāo)記密碼而不標(biāo)記用戶名是不合法的铐维。
4)Keep Alive柬泽,表示響應(yīng)時間,如果這個時間內(nèi)嫁蛇,連接或發(fā)送操作未完成锨并,則斷開tcp連接,表示離線睬棚。
5)Connect Return Code即通常于CONNACK消息中琳疏,表示返回的連接情況有决,我可以通過此檢驗連接情況。
6)Topic name(主題名稱):訂閱消息標(biāo)識空盼,MQTT是基于訂閱/發(fā)布的消息书幕,那么這個就是消息訂閱的標(biāo)識,像新聞客戶端里的訂閱不同的欄目一樣揽趾。用于區(qū)別消息的推送類別台汇。
主要用于PUBLISH和SUBSCRIBE中。最大可支持32767個字符篱瞎,即4個字節(jié)苟呐。
3、消息體(PayLoad)
只有3種消息有消息體CONNECT俐筋,SUBSCRIBE牵素,SUBACK。
CONNECT主要是客戶機(jī)的ClientID澄者,訂閱的Topic和Message以及用戶名和密碼笆呆,其于變長頭部中的will是對應(yīng)的。
SUBSCRIBE是包含了一系列的要訂閱的主題以及QOS粱挡。
SUBACK是用服務(wù)器對于SUBSCRIBE所申請的主題及QOS進(jìn)行確認(rèn)和回復(fù)赠幕。
而PUBLISH是消息體中則保存推送的消息,以二進(jìn)制形式询筏,當(dāng)然這里的編輯可自定義榕堰。
4、Message Identifier:消息標(biāo)識符存在于以下MQTT消息的變量頭中:PUBLISH嫌套,PUBACK逆屡,PUBREC,PUBREL踱讨,PUBCOMP魏蔗,SUBSCRIBE,SUBACK勇蝙,UNSUBSCRIBE沫勿,UNSUBACK挨约。
消息標(biāo)識符(Message ID)字段僅存在于固定報頭中的QoS位表示QoS級別1或2的消息中味混。其為16位字符表示,用于在Qos為1或2時標(biāo)識Message的诫惭,保證Message傳輸?shù)目煽啃浴?/p>