目錄
前言
本筆記記錄 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