MQTT-SN協議亂翻之小結篇

前言

這裏簡單作一些小結和對比,針對前面的協議翻譯部分,一階段的學習完結。html

MQTT-SN VS MQTT

MQTT-SN基於MQTT原有語義,但作了不少的調整。好比: 一個CONNECT消息被拆分爲3個消息 主題名稱須要使用主題標識符替代 * 網關地址能夠廣播、查詢得知java

MQTT-SN 與 MQTT對比,使用一張圖介紹git

比較類型 MQTT MQTT-SN
傳輸類型 可靠點對點流模式 不可靠的數據報
通訊方式 TCP/IP Non-IP 或 UDP
網絡傳輸 Ethernet, WiFi, 3G ZigBee,Bluetooth,RF
最小消息 2個字節 2個字節
最大消息 ≤24MB < 128個字節
電池供電 X
休眠支持 X
QoS -1(啞客戶端) X
主題標識符 X
網關自動發現和回退 X

QoS

有關QoS,MQTT-SN新增增長了啞客戶端(QoS :-1)支持:後端

QoS Level 消息傳輸次數 傳輸語義 傳輸保證
-1 ≤ 1 至多一次 無鏈接,只用於傳輸,盡力而爲,無保證;只有MQTT-SN支持
0 ≤ 1 至多一次 盡力而爲,無保證
1 ≥ 1 至少一次 保證送達,可能存在重複
-1 ≡ 1 只有一次 保證送達,而且不存在重複

網關的查詢和發現

  1. MQTT-SN客戶端無須提早知道網關地址,接收網關的週期性廣播好了,或直接廣播一條網關查詢;接收廣播+主動查詢,就夠了
  2. MQTT-SN對客戶端/網關的亂入和丟失,處理的很好,備用網關在主網關掛掉以後便可轉換爲主網關,針對客戶端而言,直接更新一個新的網關地址就能夠
  3. 存在的若干網關能夠互相協調彼此之間角色,互爲主備stand-by,出現問題,主機下線維護,從機升級主機

清理會話

和MQTT 3.1協議相似,在上一次的客戶端成功鏈接時在CONNECT中設置了清理會話標誌clean session爲false,遺囑特性Will也爲true,再次鏈接時,那麼服務器爲其緩存訂閱數據和遺囑數據是否已經被刪除,對客戶端不透明,由於就算是服務器因內存壓力等清理了緩存,但沒有通知到客戶端,會形成訂閱、遺囑的誤解。緩存

還好,MQTT-SN協議中,網關在清理掉遺囑數據後,能夠諮詢客戶端,或主動通知客戶端斷開,從新創建會話流程。服務器

在MQTT 3.1.1協議中,服務器會在CONNACK中標記會話是否已經被持久的標記。網絡

主題標識符(Topic id)

確切來講,MQTT-SN協議存在三種格式主題名稱(topic name),可由消息標誌位包含TopicIdType屬性決定:session

  • 0b01:預分配的主題標識符(topic id),16位天然數,0-65535範圍
  • 0b10:預分配的短主題名稱(short topic name),只有兩個字符表示
  • 0b00:正常主題名稱(topic name),可直接附加在REGISTER/SUBSCRIBE/WILLTOPICUPD消息對應字段中

全部主題被替換成標識符,在發佈PUBLISH消息時,直接使用被指定的主題標識符topic id、short topic name便可。架構

MQTT-SN流程梳理

下面對MQTT-SN經常使用流程進行的流程簡單梳理:eclipse

Client              Gateway            Server/Broker
                |                   |                    |
Generic Process | --- SERCHGW ----> |                    |
                | <-- GWINFO  ----- |                    |
                | --- CONNECT ----> |                    |
                | <--WILLTOPICREQ-- |                    |
                | --- WILLTOPIC --> |                    |
                | <-- WILLMSGREQ -- |                    |
                | --- WILLMSG ----> | ---- CONNECT ----> |(accepted)
                | <-- CONNACK ----- | <--- CONNACK ----- |
                | --- PUBLISH ----> |                    |
                | <-- PUBACK  ----- | (invalid TopicId)  |
                | --- REGISTER ---> |                    |
                | <-- REGACK  ----- |                    |
                | --- PUBLISH ----> | ---- PUBLISH ----> |(accepted)
                | <-- PUBACK  ----- | <---- PUBACK ----- |
                |                   |                    |
                //                  //                   //
                |                   |                    |
 SUBSCRIBE   -->| --- SUBSCRIBE --> | ---- SUBSCRIBE --> |
 [var Callback] | <-- SUBACK ------ | <--- SUBACK ------ |
                |                   |                    |
                //                  //                   //
                |                   |                    |
                | <-- REGISTER ---- | <--- PUBLISH ----- |<-- PUBLISH
                | --- REGACK  ----> |                    |
[exec Callback] | <-- PUBLISH  ---- |                    |
                | --- PUBACK   ---> | ---- PUBACK  ----> |--> PUBACK
                |                   |                    |
                //                  //                   //
                |                   |                    |
active -> asleep| --- DISCONNECT -> | (with duration)    |
                | <-- DISCONNECT -- | (without duration) |
                |                   |                    |
                //                  //                   //
                |                   |                    |
                |                   | <--- PUBLISH ----- |<-- PUBLISH
                |                   | ----- PUBACK ----> |
                |                   | <--- PUBLISH ----- |<-- PUBLISH
                |                   | ----- PUBACK ----> |
                |                   | (buffered messages)|
asleep -> awake |                   |                    |
                | --- PINGREQ ----> |                    |
awake state     | <-- PUBLISH  ---- |                    |
                | <-- PUBLISH  ---- |                    |
                | <-- PINGRESP ---- |                    |
asleep <-awake  |                   |                    |

MQTT-SN運行的協議棧

MQTT-SN能夠運行在不一樣的無線協議上,只要能夠知足MQTT-SN 所定義便可:支持雙向數據傳輸和網關便可,MQTT-SN徹底能夠運行在其上面。

MQTT-SN能夠在ZigBee、Bluetooth、RF、UDP、6loWPAN等底層協議層面運行。

MQTT-SN網絡拓撲圖

下面是來自網友的基於MQTT-SN運行的架構圖:

但實際上的其網絡拓撲可能更爲複雜,好比兩個不一樣的傳感器網絡:

小結

傳感器和制動器,合稱爲SA。傳感器彙報狀態數值(自身發佈PUBLISH消息),制動器會被某參數值觸發(接收到的PUBLISH消息)。比如,文件的輸入-輸出模式,傳感器用於文件的讀取,制動器用於文件寫入。或者使用管道閥門,某指標超過閥值觸發制動器報警,SA一塊兒做用便於更好追蹤數據。大部分時間,PUBLISH消息被用於觸發制動器,這創建在後端服務器的分析結果基礎上。

MQTT-SN比較知名的實現,好比(http://eclipse.org/proposals/technology.mosquitto/)[Eclipse Mosquitto],(RMSB)[http://git.eclipse.org/c/mosquitto/org.eclipse.mosquitto.rsmb.git/]等,但不是實現全部已定義細節,好比MQTT-SN協議轉發部分(MQTT-SN Forwarder),就鮮有實現,但實現不難嘛,可能缺少相應的場景支持吧。

MQTT-SN支持相似於傳感器的網關,稍強的網絡可與適用於MQTT協議,這樣看來,MQTT要作到鏈接一切(Connect anything),如IBM所發佈的紅皮書所說,要使用MQTT打造一個智能星球,有戲!

 

原文 http://www.blogjava.net/yongboy/archive/2015/01/13/422207.html

相關文章
相關標籤/搜索