Mqtt協議規範

百聯達發表於2014-06-06

MQTT(Message Queue Telemetry Transport),遙測傳輸協議,提供訂閱/釋出模式,更為簡約、輕量,易於使用,針對受限環境(頻寬低、網路延遲高、網路通訊不穩定),可以簡單概括為物聯網打造,官方總結特點如下:

1.使用釋出/訂閱訊息模式,提供一對多的訊息釋出,解除應用程式耦合。
2. 對負載內容遮蔽的訊息傳輸。
3. 使用 TCP/IP 提供網路連線。
4. 有三種訊息釋出服務質量:
    “至多一次”,訊息釋出完全依賴底層 TCP/IP 網路。會發生訊息丟失或重複。這一級別可用於如下情況,環境感測器資料,丟失一次讀記錄無所謂,因為不久後還會有第二次傳送。
    “至少一次”,確保訊息到達,但訊息重複可能會發生。
    “只有一次”,確保訊息到達一次。這一級別可用於如下情況,在計費系統中,訊息重複或丟失會導致不正確的結果。
5. 小型傳輸,開銷很小(固定長度的頭部是 2 位元組),協議交換最小化,以降低網路流量。
6. 使用 Last Will 和 Testament 特性通知有關各方客戶端異常中斷的機制。 

                                                                                         
訊息格式


                                                                                                                                                                                                                             
一:固定頭部
MQTT的訊息包含著一個有兩個位元組大小的固定頭部
bit 7 6 5 4 3 2 1 0
byte 1 Message Type DUP flag QoS level RETAIN
byte 2 Remaining Length
二:訊息型別(Message Tpe)

訊息型別(4-7),使用4位二進位制表示,可代表16種訊息型別:

Mnemonic Enumeration Description
Reserved 0 Reserved----保留待用
CONNECT 1 Client request to connect to Server----客戶端連線請求
CONNACK 2 Connect Acknowledgment----連線反饋
PUBLISH 3 Publish message-----釋出訊息
PUBACK 4 Publish Acknowledgment-----釋出反饋
PUBREC 5 Publish Received (assured delivery part 1)----釋出訊息被接收
PUBREL 6 Publish Release (assured delivery part 2)
PUBCOMP 7 Publish Complete (assured delivery part 3)----釋出訊息完成
SUBSCRIBE 8 Client Subscribe request----客戶端訂閱
SUBACK 9 Subscribe Acknowledgment----訂閱反饋
UNSUBSCRIBE 10 Client Unsubscribe request----客戶端解除訂閱
UNSUBACK 11 Unsubscribe Acknowledgment----接觸訂閱反饋
PINGREQ 12 PING Request-------心跳檢測
PINGRESP 13 PING Response----心跳反饋
DISCONNECT 14 Client is Disconnecting----客戶端斷開連線
Reserved 15 Reserved----保留待用

三:DUP flag(開啟標誌)

保證訊息可靠傳輸,預設為0,只佔用一個位元組,表示第一次傳送。不能用於檢測訊息重複傳送等。只適用於客戶端或伺服器端嘗試重發PUBLISH, PUBREL, SUBSCRIBE 或 UNSUBSCRIBE訊息,注意需要滿足以下條件:

 當QoS > 0
 訊息需要回復確認 

此時,在可變頭部需要包含訊息ID。當值為1時,表示當前訊息先前已經被傳送過。

四:QoS(Quality of Service,服務質量)

使用兩個二進位制表示PUBLISH型別訊息:

QoS value bit 2 bit 1 Description
0 0 0 至多一次 發完即丟棄 <=1
1 0 1 至少一次 需要確認回覆 >=1
2 1 0 只有一次 需要確認回覆 =1
3 1 1 待用,保留位置

五:RETAIN(保持)

僅針對PUBLISH訊息。不同值,不同含義:

1:表示傳送的訊息需要一直持久儲存(不受伺服器重啟影響),不但要傳送給當前的訂閱者,並且以後新來的訂閱了此Topic name的訂閱者會馬上得到推送。

備註:新來乍到的訂閱者,只會取出最新的一個RETAIN flag = 1的訊息推送。

0:僅僅為當前訂閱者推送此訊息。

假如伺服器收到一個空訊息體(zero-length payload)、RETAIN = 1、已存在Topic name的PUBLISH訊息,伺服器可以刪除掉對應的已被持久化的PUBLISH訊息。


六:QoS level決定的訊息流

QoS level為Quality of Service level的縮寫,翻譯成中文,服務質量等級。

MQTT 3.1協議在"4.1 Quality of Service levels and flows"章節中,僅僅討論了客戶端到伺服器的釋出流程,不太完整。因為決定訊息到達率,能夠提升傳送質量的,應該是伺服器釋出PUBLISH訊息到訂閱者這一訊息流方向。

QoS level 0

至多傳送一次,傳送即丟棄。沒有確認訊息,也不知道對方是否收到。

Client Message and direction Server
QoS = 0 PUBLISH 
----------&gt
Action: Publish message to subscribers then Forget
Reception: <=1

針對的訊息不重要,丟失也無所謂。

網路層面,傳輸壓力小。

QoS level 1

所有QoS level 1都要在可變頭部中附加一個16位的訊息ID。

SUBSCRIBE和UNSUBSCRIBE訊息使用QoS level 1。

針對訊息的釋出,Qos level 1,意味著訊息至少被傳輸一次。

傳送者若在一段時間內接收不到PUBACK訊息,傳送者需要開啟DUB標記為1,然後重新傳送PUBLISH訊息。因此會導致接收方可能會收到兩次PUBLISH訊息。針對客戶端釋出訊息到伺服器的訊息流:

Client Message and direction Server
QoS = 1
DUP = 0
Message ID = x

Action: Store message

PUBLISH 
----------&gt
Actions:
  • Store message

  • Publish message to subscribers
  • Delete message

Reception: >=1
Action: Discard message PUBACK 
Message ID = x

針對伺服器釋出到訂閱者的訊息流:

Server Message and direction Subscriber
QoS = 1
DUP = 0
Message ID = x
PUBLISH 
----------&gt
Actions:
  • Store message

  • Make message available                       
Reception: >=1

PUBACK 
Message ID = x

釋出者(客戶端/伺服器)若因種種異常接收不到PUBACK訊息,會再次重新傳送PUBLISH訊息,同時設定DUP標記為1。接收者以伺服器為例,這可能會導致伺服器收到重複訊息,按照流程,broker(伺服器)釋出訊息到訂閱者(會導致訂閱者接收到重複訊息),然後傳送一條PUBACK確認訊息到釋出者。

在業務層面,或許可以彌補MQTT協議的不足之處:重試的訊息ID一定要一致接收方一定判斷當前接收的訊息ID是否已經接受過

但一樣不能夠完全確保,訊息一定到達了。

QoS level 2

僅僅在PUBLISH型別訊息中出現,要求在可變頭部中要附加訊息ID。

級別高,通訊壓力稍大些,但確保了僅僅傳輸接收一次。

先看協議中流程圖,Client -> Server方向,會有一個總體印象:

Client Message and direction Server
QoS = 2
DUP = 0
Message ID = x

Action: Store message

PUBLISH 
----------&gt
Action(a) Store message

or

Actions(b):
  • Store message ID
  • Publish message to subscribers
  PUBREC 
Message ID = x
Message ID = x PUBREL 
----------&gt
Actions(a):
  • Publish message to subscribers
  • Delete message

or

Action(b): Delete message ID
Action: Discard message PUBCOMP 
Message ID = x

Server -> Subscriber

Server Message and direction Subscriber
QoS = 2
DUP = 0
Message ID = x
PUBLISH 
----------&gt
Action: Store message
  PUBREC 
Message ID = x
Message ID = x PUBREL 
----------&gt
Actions:
  • Make message available                       

PUBCOMP 
Message ID = x

Server端採取的方案a和b,都包含了何時訊息有效,何時處理訊息。兩個方案二選一,Server端自己決定。但無論死採取哪一種方式,都是在QoS level 2協議範疇下,不受影響。若一方沒有接收到對應的確認訊息,會從最近一次需要確認的訊息重試,以便整個(QoS level 2)流程打通。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28624388/viewspace-1176994/,如需轉載,請註明出處,否則將追究法律責任。

相關文章