MQTT協(xié)議之連接和心跳介紹

本篇會把連接(CONNECT)敲董、心跳(PINGREQ/PINGRESP)、確認(CONNACK)底洗、斷開連接(DISCONNECT)和在一起進行介紹款筑。

在閱讀本文之前推薦大家先讀一下我的前兩篇文章:MQTT協(xié)議及應(yīng)用場景 MQTT協(xié)議之頭部信息介紹

CONNECT

MQTT v3.1.1有關(guān)字符串部分采用的修改版的UTF-8編碼智蝠,CONNECT可變頭部中協(xié)議名稱、消息體都是采用修改版的UTF-8編碼奈梳。前面基本上可變頭部內(nèi)容不多寻咒,下面是一個較為完整的CONNECT消息結(jié)構(gòu):

mqtt connect消息結(jié)構(gòu)

協(xié)議變化
MQTT 3.1.1中CONNECT消息可變頭部協(xié)議名稱MQIsdp被改為MQTT。
MQTT 3.1.1中所有字符串明確規(guī)定使用UTF-8編碼颈嚼,包括客戶端標識符(Client Identifier)毛秘。
MQTT 3.1.1中針對客戶端標識符( client identifier)限制由原來的23個字節(jié)上限改為65535個字節(jié)。
MQTT 3.1.1中CONNECT消息可變頭部協(xié)議版本號,由0x03變成了0x04 QoS 0類型PUBLISH消息DUP標記必須被設(shè)置為0叫挟。
MQTT 3.1.1中MQTT Over WebSocket 被定義艰匙,互聯(lián)網(wǎng)地址編碼分配機構(gòu)(Internet Assigned Numbers Authority)分配標識符為mqtt。雖在MQTT 3.1規(guī)范通篇沒有提到WebSocket抹恳,但因其二進制屬性可以很容易的在WebSocket通道傳輸员凝。


術(shù)語變化

  • MQTT代理 -> MQTT服務(wù)器(MQTT Broker is now MQTT Server)
  • 消息ID -> 包ID(Message ID is now Packet ID)
  • 消息類型 -> 包類型(Message Type is now Packet Type)
  • 主題路徑 -> 主題名稱(Subscribe and Unsubscribe take Topic Paths, rather than Topic names)
  • 以前在固定頭部,現(xiàn)在在包類型中( Flags in the fixed header are now specific to the packet type
  • 0字節(jié)保留信息需要清除 (A zero byte retained message MUST NOT be stored as a retained message on the Server )

可變頭部

協(xié)議名稱和協(xié)議版本都是固定的奋献。

連接標志(Connect Flags)

一個字節(jié)表示健霹,除了第1位是保留未使用,其它7位都具有不同含義瓶蚂。業(yè)務(wù)上很重要糖埋,對消息總體流程影響很大,需要牢記窃这。

Clean Session

0瞳别,表示如果訂閱的客戶機斷線了,要保存為其要推送的消息(QoS為1和QoS為2)杭攻,若其重新連接時祟敛,需將這些消息推送(若客戶端長時間不連接,需要設(shè)置一個過期值)兆解。 1馆铁,斷線服務(wù)器即清理相關(guān)信息,重新連接上來之后锅睛,會再次訂閱埠巨。

Will Flag

定義了客戶端(沒有主動發(fā)送DISCONNECT消息)出現(xiàn)網(wǎng)絡(luò)異常導(dǎo)致連接中斷的情況下,服務(wù)器需要做的一些措施衣撬。
  簡而言之乖订,就是客戶端預(yù)先定義好扮饶,在自己異常斷開的情況下具练,所留下的最后遺愿(Last Will),也稱之為遺囑(Testament)甜无。 這個遺囑就是一個由客戶端預(yù)先定義好的主題和對應(yīng)消息扛点,附加在CONNECT的可變頭部中,在客戶端連接出現(xiàn)異常的情況下岂丘,由服務(wù)器主動發(fā)布此消息陵究。
  只有在Will Flag位為1時,Will Qos和Will Retain才會被讀取奥帘,此時消息體payload中要出現(xiàn)Will Topic和Will Message具體內(nèi)容铜邮,否則,Will QoS和Will Retain值會被忽略掉。

Will Qos

兩位表示松蒜,和PUBLISH消息固定頭部的QoS level含義一樣扔茅。這里先略過,到PUBLISH消息再回過頭來看看秸苗,會更明白些召娜。若標識了Will Flag值為1,那么Will QoS就會生效惊楼,否則會被忽略掉玖瘸。

Will Retain

如果設(shè)置Will Flag,Will Retain標志就是有效的檀咙,否則它將被忽略雅倒。當客戶端意外斷開服務(wù)器發(fā)布其Will Message之后,服務(wù)器是否應(yīng)該繼續(xù)保存攀芯。這個屬性和PUBLISH固定頭部的RETAIN標志含義一樣屯断,這里先略過。

User name 和 password Flag

用于授權(quán)侣诺,兩者要么為0要么為1殖演,否則都是無效。都為0年鸳,表示客戶端可自由連接/訂閱趴久,都為1,表示連接/訂閱需要授權(quán)搔确。

Payload/消息體

消息體定義的消息順序(如上表所示)彼棍,約定俗成,不得更改膳算,否則將可能引起混亂座硕。
  若Will Flag值為0,那么在payload中涕蜂,Client Identifer后面就不會存在Will Topic和Will Message內(nèi)容华匾。
  若User Name和Password都為0,意味著Payload/消息體中机隙,找不到User Name和password的值蜘拉,就算有,也是無效有鹿。標志決定著是否讀取與否旭旭。

心跳時間(Keep Alive timer)

以秒為單位,定義服務(wù)器端從客戶端接收消息的最大時間間隔葱跋。一般應(yīng)用服務(wù)會在業(yè)務(wù)層次檢測客戶端網(wǎng)絡(luò)是否連接持寄,不是TCP/IP協(xié)議層面的心跳機制(比如開啟SOCKET的SO_KEEPALIVE選項)源梭。 一般來講,在一個心跳間隔內(nèi)稍味,客戶端發(fā)送一個PINGREQ消息到服務(wù)器咸产,服務(wù)器返回PINGRESP消息,完成一次心跳交互仲闽,繼而等待下一輪脑溢。若客戶端沒有收到心跳反饋,會關(guān)閉掉TCP/IP端口連接赖欣,離線屑彻。 16位兩個字節(jié),可看做一個無符號的short類型值顶吮。最大值社牲,2^16-1 = 65535秒 = 18小時。最小值可以為0悴了,表示客戶端不斷開搏恤。一般設(shè)為幾分鐘,比如微信心跳周期為300秒湃交。

Will Message編碼

Will Message在CONNECT Payload/息體中熟空,使用UTF-8編碼。假設(shè)內(nèi)容為“abcd”搞莺,大概如下:


mqtt connect will message

注:PUBLISH的Payload/消息體中以二進制編碼保存

在某一時間點客戶端異常關(guān)閉會觸發(fā)服務(wù)器PUBLISH此消息息罗。那么服務(wù)器會直接把byte3-byte6之間字符取出,保存為二進制才沧,附加到PUBLISH消息體中迈喉,大概存儲如下:


mqtt publish will message

連接異常中斷通知機制

CONNECT消息一旦設(shè)置在可變頭部設(shè)置了Will flag標記,那就啟用了Last-Will-And-Testament特性温圆,此特性很贊挨摸。
  一旦客戶端出現(xiàn)異常中斷,便會觸發(fā)服務(wù)器發(fā)布Will Message消息到Will Topic主題上去岁歉,通知Will Topic訂閱者得运,對方因異常退出。

CONNACK

收到CONNECT消息之后刨裆,服務(wù)器應(yīng)該返回一個CONNACK消息作為響應(yīng):

  • 若客戶端繞過CONNECT消息直接發(fā)送其它類型消息澈圈,服務(wù)器應(yīng)關(guān)閉此非法連接 若客戶端發(fā)送CONNECT之后未收到CONNACT彬檀,需要關(guān)閉當前連接帆啃,然后重新連接
  • 相同Client ID客戶端已連接到服務(wù)器,先前客戶端必須斷開連接后窍帝,服務(wù)器才能完成新的客戶端CONNECT連接 客戶端發(fā)送無效非法CONNECT消息努潘,服務(wù)器需要關(guān)閉。
      一個完整的CONNACK消息大致如下:
    connack

      可變頭部第一個字節(jié)為保留,無甚用處疯坤。第二個字節(jié)為連接握手返回碼:
    connack response code

      只有0-5目前被使用到报慕,其他值有待日后使用。一般返回值為0x00压怠,表示連接建立眠冈。非法的請求,需要返回相應(yīng)的數(shù)值菌瘫。
      從上面看出蜗顽,一個CONNACK,四個字節(jié)表示雨让。一個正常的CONNACK消息實際內(nèi)容可能如下:
    0x20 0x02 0x00 0x00 
      若是在私有協(xié)議中雇盖,兩個字節(jié)就足夠了。很多時候栖忠,客戶端和服務(wù)器端在沒有消息傳遞時崔挖,會一直保持著連接。雖然不能依靠TCP心跳機制(比如SO_KEEPALIVE選項)庵寞,業(yè)務(wù)層面定義心跳機制狸相,會讓連接狀態(tài)檢測、控制更為直觀捐川。

PINGREQ

由客戶端發(fā)送到服務(wù)器端卷哩,證明自己還在一直連接著呢。兩個字節(jié)属拾,固定值将谊。


PINGREQ

  客戶端會在一個心跳周期內(nèi)發(fā)送一條PINGREQ消息到服務(wù)器端。心跳頻率在CONNECT可變頭部“Keep Alive Timer”中定義時間渐白,單位為秒尊浓,無符號16位short表示。

PINGRESP

服務(wù)器收到PINGREQ請求之后纯衍,會立即響應(yīng)一個兩個字節(jié)固定格式的PINGRESP消息栋齿。

PINGRESP

  服務(wù)器一般若在1.5倍的心跳周期內(nèi)接收不到客戶端發(fā)送的PINGREQ,可考慮關(guān)閉客戶端的連接描述符襟诸。此時的關(guān)閉連接的行為和接收到客戶端發(fā)送DISCONNECT消息的處理行為一致瓦堵,但對客戶端的訂閱不會產(chǎn)生影響(不會清除客戶端訂閱數(shù)據(jù)),這個需要牢記歌亲。
  若客戶端發(fā)送PINGREQ之后的一個心跳周期內(nèi)接收不到PINGRESP消息菇用,可考慮關(guān)閉TCP/IP套接字連接。

DISCONNECT

客戶端主動發(fā)送到服務(wù)器端陷揪,表明即將關(guān)閉TCP/IP連接惋鸥。此時要求服務(wù)器要完整杂穷、干凈的進行斷開處理,不能僅僅類似于關(guān)閉連接描述符類似草草處理之卦绣。 需要兩個字節(jié)耐量,值固定。


DISCONNECT

  服務(wù)器要根據(jù)先前此客戶端在發(fā)送CONNECT消息可變頭部Connect flag中的“Clean session flag”所設(shè)置值滤港。
復(fù)習(xí)一下:

  1. 值為0廊蜒,服務(wù)器必須在客戶端斷開之后繼續(xù)存儲/保持客戶端的訂閱狀態(tài)。這些狀態(tài)包括:
  • 存儲訂閱的消息QoS1和QoS2消息
  • 正在發(fā)送消息期間連接丟失導(dǎo)致發(fā)送失敗的消息溅漾。
  • 以便當客戶端重新連接時以上消息可以被重新傳遞劲藐。
  • 值為1,服務(wù)器需要立刻清理連接狀態(tài)數(shù)據(jù)樟凄。

注意:服務(wù)器在接收到客戶端發(fā)送的DISCONNECT消息之后聘芜,需要主動關(guān)閉TCP/IP連接。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缝龄,一起剝皮案震驚了整個濱河市汰现,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌叔壤,老刑警劉巖瞎饲,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異炼绘,居然都是意外死亡嗅战,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門俺亮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來驮捍,“玉大人,你說我怎么就攤上這事脚曾《遥” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵本讥,是天一觀的道長珊泳。 經(jīng)常有香客問我,道長拷沸,這世上最難降的妖魔是什么色查? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮撞芍,結(jié)果婚禮上秧了,老公的妹妹穿的比我還像新娘。我一直安慰自己勤庐,他們只是感情好示惊,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著愉镰,像睡著了一般米罚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丈探,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天录择,我揣著相機與錄音,去河邊找鬼碗降。 笑死隘竭,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的讼渊。 我是一名探鬼主播动看,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼爪幻!你這毒婦竟也來了菱皆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤挨稿,失蹤者是張志新(化名)和其女友劉穎仇轻,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奶甘,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡篷店,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了臭家。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疲陕。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖钉赁,靈堂內(nèi)的尸體忽然破棺而出鸭轮,到底是詐尸還是另有隱情,我是刑警寧澤橄霉,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布窃爷,位于F島的核電站,受9級特大地震影響姓蜂,放射性物質(zhì)發(fā)生泄漏按厘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一钱慢、第九天 我趴在偏房一處隱蔽的房頂上張望逮京。 院中可真熱鬧,春花似錦束莫、人聲如沸懒棉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽策严。三九已至穗慕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間妻导,已是汗流浹背逛绵。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留倔韭,地道東北人术浪。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像寿酌,于是被迫代替她去往敵國和親胰苏。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理醇疼,服務(wù)發(fā)現(xiàn)碟联,斷路器,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • MQTT Protocol MQTT協(xié)議特性 一句話總結(jié):MQTT是一個簡單僵腺,輕量的消息發(fā)布/訂閱協(xié)議鲤孵。 MQTT...
    福克斯記閱讀 7,231評論 0 9
  • 前言 接到任務(wù)項目需要用MQTT來寫消息推送辰如,經(jīng)過一段時間在網(wǎng)上查看資料后寫下這篇文章普监,文章內(nèi)容大都來自互聯(lián)網(wǎng),在...
    Hank_Zhong閱讀 16,502評論 69 51
  • 前言 MQTT(Message Queue Telemetry Transport),遙測傳輸協(xié)議琉兜,提供訂閱/發(fā)布...
    技術(shù)學(xué)習(xí)閱讀 3,632評論 4 8
  • 實現(xiàn)效果 JS實現(xiàn)瀏覽器全屏 實現(xiàn)方式對比 1凯正、ActiveXObject 只支持IE 2、FullScreen(...
    過橋閱讀 2,594評論 0 3