目錄
前言
本筆記記錄 MQTT 相關概念。
原文:李柱明博客:https://www.cnblogs.com/lizhuming/p/14994943.html
1. MQTT 簡介
MQTT(Message Queuing Telemetry Transport)是運行在 TCP/IP 中的應用層協議,主流依賴於 TCP 協議。(也有依賴於 UDP 的)
特點:
- 開放消息協議,簡單易實現。
- 發布訂閱模式,一對多消息發布。
- 基於TCP/IP網絡連接,提供有序,無損,雙向連接。
- 1字節固定報頭,2字節心跳報文,最小化傳輸開銷和協議交換,有效減少網絡流量。
- 消息QoS支持,可靠傳輸保證。
特性:
- 使用發布/訂閱消息模式,提供一對多的消息發布,解除應用程序耦合。
- 對負載內容屏蔽的消息傳輸。
- 使用TCP/IP提供網絡連接。
- 有三種消息發布服務質量:
- QoS0:最多發送一次消息,在消息發送出去后,接收者不會發送回應,發送者也不會重發消息。
- QoS1:最少發送一次消息(消息最少需要送達一次,也有可送達多次),QoS 1的PUBLISH報文的可變報頭中包含一個報文標識符,需要PUBACK報文確認。即需要接收者返回PUBACK應答報文。
- QoS2:這是最高等級的服務質量,消息丟失和重復都是不可接受的,只不過使用這個服務質量等級會有額外的開銷。
- 小型傳輸,開銷很小(固定長度的頭部是2字節),協議交換最小化,以降低網絡流量。
- 使用Last Will和Testament特性通知有關各方客戶端異常中斷的機制:
- Last Will:即遺言機制,用於通知同一主題下的其他設備發送遺言的設備已經斷開了連接。
- Testament:遺囑機制,功能類似於Last Will。
2. MQTT 通信模型
通信模型:
2.1 MQTT 協議
MQTT 協議中有三種身份:
- 發布者(Publish):客戶端。消息發布者也可以同時是訂閱者。
- 服務器(Broker):服務端。
- 訂閱者(Subscribe):客戶端。
MQTT 傳輸的消息分為:主題(Topic)和負載(payload):
- Topic:可以理解為消息的類型,訂閱者訂閱(Subscribe)后,就會收到該主題的消息內容(payload)。
- 發布者與訂閱者可以通過主題名字進行匹配的。
- payload:可以理解為消息的內容,是指訂閱者具體要使用的內容。
2.2 MQTT 協議中的訂閱&主題&會話
訂閱(Subscription):
- 訂閱包含主題篩選器(Topic Filter)和最大服務質量(QoS)。
- 訂閱會與一個會話(Session)關聯。一個會話可以包含多個訂閱。每一個會話中的每個訂閱都有一個不同的主題篩選器。
會話(Session):
- 每個客戶端與服務器建立連接后就是一個會話,客戶端和服務器之間有狀態交互。
- 會話存在於一個網絡之間,也可能在客戶端和服務器之間跨越多個連續的網絡連接。
主題名(Topic Name):
- 連接到一個應用程序消息的標簽,該標簽與服務器的訂閱相匹配。
- 服務器會將消息發送給訂閱所匹配標簽的每個客戶端。
主題篩選器(Topic Filter):
- 一個對主題名通配符篩選器,在訂閱表達式中使用,表示訂閱所匹配到的多個主題。
負載(Payload):
- 消息訂閱者所具體接收的內容。
2.3 MQTT 協議中的方法
主要方法有:
- Connect:等待與服務器建立連接。
- Disconnect:等待MQTT客戶端完成所做的工作,並與服務器斷開TCP/IP會話。
- Subscribe:等待完成訂閱。
- UnSubscribe:等待服務器取消客戶端的一個或多個topics訂閱。
- Publish:MQTT客戶端發送消息請求,發送完成后返回應用程序線程。
3. MQTT 協議數據包結構
一個MQTT數據包由三部分組成:
- 固定報頭(Fixed header):表示數據包類型及數據包的分組類標識。
- 可變報頭(Variable header):數據包類型決定了可變頭是否存在及其具體內容。
- 有效載荷(payload):表示客戶端收到的具體內容。
3.1 固定報頭
固定報頭組成:
控制報文的類型 [7:4]:
- 4 bit,共16種。(0、15被系統保留了)
類型 | 值 | 說明 |
---|---|---|
Reserved | 0 | 系統保留 |
CONNECT | 1 | 客戶端請求連接服務端 |
CONNACK | 2 | 連接報文確認 |
PUBLISH | 3 | 發布消息 |
PUBACK | 4 | 消息發布收到確認(QoS 1) |
PUBREC | 5 | 發布收到(QoS2) |
PUBREL | 6 | 發布釋放(QoS2) |
PUBCOMP | 7 | 消息發布完成(QoS2) |
SUBSCRIBE | 8 | 客戶端訂閱請求 |
SUBACK | 9 | 訂閱請求報文確認 |
UNSUBSCRIBE | 10 | 客戶端取消訂閱請求 |
UNSUBACK | 11 | 取消訂閱報文確認 |
PINGREQ | 12 | 心跳請求 |
PINGRESP | 13 | 心跳響應 |
DISCONNECT | 14 | 客戶端斷開連接 |
Reserved | 15 | 系統保留 |
控制報文類型的標志位 [3:0]:
- 目前除了 PUBLISH類型報文 以外,其他報文的標志位均為系統保留。
- PUBLISH類型報文的標志位:
- bit3:控制報文的重復分發標志(DUP)。
- bit2-bit1:服務質量等級。
- 00:QoS0。
- 01:QoS1。
- 10:QoS2。
- 11:預留。
- bit0:PUBLISH 報文的保留標志。
剩余長度:(第二byte開始)
- 用於記錄剩余報文長度的,表示當前的消息剩余的字節數。包括可變報頭和有效載荷區域(如果存在),但剩余長度不包括用於編碼剩余長度字段本身的字節數。
- 剩余長度使用變長編碼方案:(大端模式)
- 每個字節的 [bit7] 表示剩余長度是否還有更多字節表示。
- 0:無。即是本字節為最后也給字節標識。
- 1:有。
- 每個字節的 [6:0]bit 表示編碼數據長度。
- 如:127:只需要一個字節即可:0x7F。128:需要兩個字節:0x80、0x01。
- 每個字節的 [bit7] 表示剩余長度是否還有更多字節表示。
3.2 可變報頭
只有某些MQTT報文才有可變報頭。
位於固定報頭和有效負載之間。
可變報頭的內容會根據報文類型的不同而有所不同。
3.3 有效載荷
有效載荷也是存在與某些報文中,不同的報文有效載荷也是不一樣的。
Payload有效載荷位於MQTT數據包的第三部分,包含CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE四種類型的消息:
- CONNECT:主要是:客戶端的ClientID、訂閱的Topic、Message以及用戶名和密碼。
- SUBSCRIBE:是一系列的要訂閱的主題以及QoS。
- SUBACK:是服務器對於SUBSCRIBE所申請的主題及QoS進行確認和回復。
- UNSUBSCRIBE:是要訂閱的主題。
參考
鏈接:
- MQTT:https://mqtt.org/
- MQTT手冊:http://mqtt.p2hp.com/
- 項目網站:https://www.eclipse.org/paho/
- Eclipse項目信息:https://projects.eclipse.org/projects/iot.paho
- mosquitto:http://mosquitto.org/documentation/
- ubuntu安裝mosquitto:https://www.jianshu.com/p/37f7ee7ead65
- CONNECT報文格式:http://www.blogjava.net/yongboy/archive/2014/02/09/409630.html