MQTT物聯(lián)網(wǎng)通信協(xié)議
部署MQTT Broker
docker run -d --name emqx-ee \
-p 1883:1883 -p 8081:8081 \
-p 8083:8083 -p 8883:8883 \
-p 8084:8084 -p 18083:18083 \
emqx/emqx-ee:latest
訪問web控制臺:http://192.168.200.154:18083
默認(rèn)用戶名/密碼:admin/public
# 用戶密碼管理
docker exec -it emqx-ee /bin/bash
./bin/emqx_ctl admins add <Username> <Password> <Tags> # Add dashboard user
./bin/emqx_ctl admins passwd <Username> <Password> # Reset dashboard user password
./bin/emqx_ctl admins del <Username> # Delete dashboard user
部署MQTT Web Client
docker pull emqx/mqttx-web:latest
docker run -d --name mqttx-web -p 80:80 emqx/mqttx-web:latest
MQTT客戶端命令行工具mqttx
mqttx <command> [options]
核心命令包括:pub(發(fā)布消息)、sub(訂閱主題)、conn(測試連接)等。
1. 發(fā)布消息(pub)
向指定主題發(fā)布消息。
基礎(chǔ)用法:
# 向主題 "test" 發(fā)布消息 "hello mqtt"
mqttx pub -t "test" -m "hello mqtt" -h "broker.emqx.io" -p 1883
常用參數(shù):
-t, --topic:指定主題(必填)-m, --message:消息內(nèi)容(必填)-h, --host:MQTT 服務(wù)器地址(默認(rèn):localhost)-p, --port:端口(默認(rèn):1883)-q, --qos:QoS 等級(0/1/2,默認(rèn):0)-r, --retain:是否為保留消息(默認(rèn):false)-u, --username:用戶名-P, --password:密碼--client-id:客戶端 ID(默認(rèn)自動生成)--protocol:協(xié)議版本(mqttv3.1.1或mqttv5,默認(rèn):mqttv3.1.1)
示例(帶認(rèn)證和 QoS 1):
mqttx pub -t "device/temp" -m '{"temp": 25}' -h "emqx-enterprise" -p 1883 -u "user1" -P "pass123" -q 1
2. 訂閱主題(sub)
訂閱指定主題并接收消息。
基礎(chǔ)用法:
# 訂閱主題 "test"
mqttx sub -t "test" -h "broker.emqx.io" -p 1883
常用參數(shù)(部分同 pub,新增):
-t, --topic:可重復(fù)指定多個(gè)主題(如-t "test1" -t "test2")-v, --verbose:顯示詳細(xì)信息(包括消息來源、QoS 等)--csv:以 CSV 格式輸出消息
示例(訂閱多個(gè)主題并顯示詳情):
mqttx sub -t "device/#" -t "sensor/+" -h "localhost" -v
3. 測試連接(conn)
檢查與 MQTT 服務(wù)器的連接是否正常。
用法:
# 測試連接到指定服務(wù)器
mqttx conn -h "broker.emqx.io" -p 1883 -u "test" -P "test"
成功會返回 Connected,失敗則顯示錯(cuò)誤原因(如認(rèn)證失敗、網(wǎng)絡(luò)不通)。
4. 其他實(shí)用命令
-
生成客戶端 ID:
mqttx utils clientid # 生成隨機(jī)客戶端 ID -
查看版本:
mqttx --version -
幫助信息:
mqttx --help # 全局幫助 mqttx pub --help # 特定命令幫助
5.高級用法示例
-
使用 MQTT 5.0 協(xié)議發(fā)布消息:
mqttx pub -t "mqtt5/test" -m "hello mqtt5" --protocol mqttv5 -h "localhost" -p 1883 -
發(fā)布 JSON 格式消息并保留:
mqttx pub -t "config" -m '{"max": 100, "min": 0}' -r true -h "broker.emqx.io" -
持續(xù)訂閱并將消息保存到文件:
mqttx sub -t "logs/#" -h "localhost" > mqtt_logs.txt # 輸出重定向到文件
MQTT 協(xié)議格式
MQTT 協(xié)議的核心是控制報(bào)文(Control Packet),所有通信均通過交換控制報(bào)文完成。一個(gè)完整的 MQTT 控制報(bào)文由固定報(bào)頭(Fixed Header)、可變報(bào)頭(Variable Header,可選) 和有效載荷(Payload,可選) 三部分組成,結(jié)構(gòu)如下:
+-------------------+-------------------+-------------------+
| 固定報(bào)頭 (必選) | 可變報(bào)頭 (可選) | 有效載荷 (可選) |
+-------------------+-------------------+-------------------+
1. 固定報(bào)頭(Fixed Header)
所有 MQTT 控制報(bào)文都必須包含固定報(bào)頭,用于標(biāo)識報(bào)文類型、QoS 等級、是否保留等核心屬性,共2 字節(jié)(基礎(chǔ)結(jié)構(gòu)),部分報(bào)文會擴(kuò)展更多字節(jié)(如剩余長度字段)。
第 1 字節(jié):控制報(bào)文類型與標(biāo)志位
第 1 字節(jié)分為高 4 位(D7-D4)和低 4 位(D3-D0):
- 高 4 位(控制報(bào)文類型):標(biāo)識報(bào)文的用途,共 14 種類型(0-15 中,15 為保留),常見類型如下:
| 類型值 | 報(bào)文類型 | 用途說明 |
|---|---|---|
| 1 | CONNECT | 客戶端向服務(wù)端發(fā)起連接請求 |
| 2 | CONNACK | 服務(wù)端向客戶端回復(fù)連接確認(rèn) |
| 3 | PUBLISH | 客戶端 / 服務(wù)端發(fā)布消息(核心報(bào)文) |
| 4 | PUBACK | 對 QoS 1 的 PUBLISH 報(bào)文的確認(rèn) |
| 5 | PUBREC | 對 QoS 2 的 PUBLISH 報(bào)文的 “接收確認(rèn)” |
| 6 | PUBREL | 對 QoS 2 的 PUBREC 報(bào)文的 “釋放確認(rèn)” |
| 7 | PUBCOMP | 對 QoS 2 的 PUBREL 報(bào)文的 “完成確認(rèn)” |
| 8 | SUBSCRIBE | 客戶端向服務(wù)端發(fā)起訂閱請求 |
| 9 | SUBACK | 服務(wù)端向客戶端回復(fù)訂閱確認(rèn) |
| 10 | UNSUBSCRIBE | 客戶端向服務(wù)端發(fā)起取消訂閱請求 |
| 11 | UNSUBACK | 服務(wù)端向客戶端回復(fù)取消訂閱確認(rèn) |
| 12 | PINGREQ | 客戶端向服務(wù)端發(fā)送 “心跳”,檢測連接狀態(tài) |
| 13 | PINGRESP | 服務(wù)端向客戶端回復(fù)心跳確認(rèn) |
| 14 | DISCONNECT | 客戶端 / 服務(wù)端主動斷開連接 |
-
低 4 位(標(biāo)志位)
:不同報(bào)文類型的標(biāo)志位含義不同,僅部分標(biāo)志位有效(無效位必須設(shè)為 0),核心標(biāo)志位如下:
D3(Retain):僅用于 PUBLISH 報(bào)文。若為 1,服務(wù)端會保留該消息,后續(xù)新訂閱該主題的客戶端會立即收到這條保留消息;若為 0,服務(wù)端不保留,僅推送給當(dāng)前訂閱者。D2-D1(QoS):僅用于 PUBLISH、SUBSCRIBE 等報(bào)文,標(biāo)識消息的 QoS 等級(00=QoS 0,01=QoS 1,10=QoS 2,11 = 保留)。D0(Dup):“重發(fā)標(biāo)志”,僅用于 PUBLISH 報(bào)文。若為 1,標(biāo)識該消息是重發(fā)的(因未收到前一次的確認(rèn));若為 0,標(biāo)識是首次發(fā)送。
第 2 字節(jié)起:剩余長度(Remaining Length)
表示 “可變報(bào)頭 + 有效載荷” 的總字節(jié)數(shù),采用可變長度編碼(1-4 字節(jié)),目的是減少報(bào)頭開銷(短消息無需占用 4 字節(jié))。
編碼規(guī)則:每個(gè)字節(jié)的最高位(D7)為 “延續(xù)位”,若為 1,表示后續(xù)還有字節(jié);低 7 位(D6-D0)為實(shí)際數(shù)值。例如:
- 若剩余長度≤127,用 1 字節(jié)表示(
D7=0,低 7 位為數(shù)值); - 若剩余長度 > 127,
D7=1,低 7 位表示 “數(shù)值的低 7 位”,后續(xù)字節(jié)繼續(xù)補(bǔ)充高位,最多 4 字節(jié)(最大可表示 4,294,967,295 字節(jié))。
2. 可變報(bào)頭(Variable Header)
并非所有報(bào)文都有可變報(bào)頭,僅特定類型(如 CONNECT、PUBLISH、SUBSCRIBE)需要,用于攜帶該報(bào)文的 “附加屬性”。常見可變報(bào)頭內(nèi)容:
- CONNECT 報(bào)文:包含 “協(xié)議名(MQTT)”、“協(xié)議級別(如 5=MQTT 5.0,4=MQTT 3.1.1)”、“連接標(biāo)志(如是否需要用戶名 / 密碼、是否清理會話)”、“保持連接(Keep Alive)時(shí)間”。
- PUBLISH 報(bào)文:包含 “主題名(Topic Name)”—— 用于標(biāo)識消息的 “目的地”,客戶端通過訂閱主題接收消息;若 QoS≥1,還包含 “報(bào)文標(biāo)識符(Packet Identifier)”(2 字節(jié),唯一標(biāo)識該消息,用于確認(rèn)和重發(fā))。
- SUBSCRIBE/SUBACK 報(bào)文:包含 “報(bào)文標(biāo)識符”(用于匹配訂閱請求與確認(rèn))。
3. 有效載荷(Payload)
也稱為 “消息體”,僅特定報(bào)文需要,用于攜帶實(shí)際數(shù)據(jù)。常見有效載荷內(nèi)容:
- CONNECT 報(bào)文:包含 “客戶端標(biāo)識符(Client ID,唯一標(biāo)識客戶端)”、“用戶名(可選)”、“密碼(可選)”。
- PUBLISH 報(bào)文:包含 “業(yè)務(wù)數(shù)據(jù)”(如傳感器采集的溫度、設(shè)備狀態(tài)等,可二進(jìn)制或文本格式)。
- SUBSCRIBE 報(bào)文:包含 “訂閱列表”(主題過濾器 + 期望的 QoS 等級,如
sensor/temp+ QoS 1)。
MQTT QoS 三個(gè)等級
QoS(Quality of Service,服務(wù)質(zhì)量)是 MQTT 的核心特性,用于在 “網(wǎng)絡(luò)不穩(wěn)定” 場景下保證消息的 “傳遞可靠性”,同時(shí)平衡 “可靠性” 與 “開銷”(QoS 越高,通信步驟越多,帶寬 / 資源消耗越大)。三個(gè)等級的核心差異是 “消息傳遞的確認(rèn)機(jī)制” 和 “可靠性保證”。
1. QoS 0:最多一次(At Most Once)
-
核心定義:消息 “最多傳遞一次”,可能丟失,但不會重復(fù)。
類比:“發(fā)短信后不等對方回復(fù)”—— 對方可能收到,也可能沒收到(如網(wǎng)絡(luò)斷連),但不會收到多條相同消息。 -
通信流程:1 步完成(無確認(rèn))
發(fā)送方(客戶端 / 服務(wù)端)→ 直接發(fā)送 PUBLISH 報(bào)文(Dup=0,QoS=00)→ 不等待確認(rèn),發(fā)送即結(jié)束。 -
適用場景
對消息可靠性要求低、允許丟失的場景,如:
- 傳感器實(shí)時(shí)采集的 “非關(guān)鍵數(shù)據(jù)”(如實(shí)時(shí)溫度,丟一條不影響整體分析);
- 設(shè)備周期性上報(bào)的 “狀態(tài)心跳”(如設(shè)備在線狀態(tài),下一次上報(bào)會覆蓋)。
-
優(yōu)缺點(diǎn):
? 優(yōu)點(diǎn):開銷最小(無確認(rèn)、無重發(fā)),適合帶寬 / 資源受限的設(shè)備(如低功耗傳感器);
? 缺點(diǎn):消息可能丟失(如網(wǎng)絡(luò)中斷時(shí))。
2. QoS 1:至少一次(At Least Once)
-
核心定義:消息 “至少傳遞一次”,確保不丟失,但可能重復(fù)。
類比:“發(fā)短信后等對方回復(fù)‘收到’,沒收到就重發(fā)”—— 對方一定會收到(可能收到多次,需業(yè)務(wù)層去重)。 -
通信流程
:2 步完成(“發(fā)送 - 確認(rèn)”)
- 發(fā)送方發(fā)送 PUBLISH 報(bào)文(Dup=0,QoS=01,帶報(bào)文標(biāo)識符);
- 接收方收到后,立即處理消息,并回復(fù)PUBACK 報(bào)文(攜帶相同的報(bào)文標(biāo)識符);
- 發(fā)送方若在 “超時(shí)時(shí)間” 內(nèi)未收到 PUBACK,會重發(fā) PUBLISH 報(bào)文(Dup=1),直到收到確認(rèn)。
-
適用場景
對消息 “不丟失” 有要求,但可接受重復(fù)的場景,如:
- 設(shè)備控制指令(如 “開燈”,重復(fù)執(zhí)行一次不影響);
- 物聯(lián)網(wǎng)設(shè)備上報(bào)的 “關(guān)鍵數(shù)據(jù)”(如電表讀數(shù),重復(fù)讀數(shù)可通過時(shí)間戳去重)。
-
優(yōu)缺點(diǎn):
? 優(yōu)點(diǎn):確保消息不丟失,可靠性高于 QoS 0;
? 缺點(diǎn):可能重復(fù)(需業(yè)務(wù)層處理去重),開銷高于 QoS 0(多一次確認(rèn))。
3. QoS 2:恰好一次(Exactly Once)
-
核心定義:消息 “恰好傳遞一次”,確保不丟失、不重復(fù),是最高可靠性等級。
類比:“發(fā)短信后,對方先回復(fù)‘已收到,待處理’,我方回復(fù)‘請?zhí)幚怼瑢Ψ教幚砗蠡貜?fù)‘已處理’”—— 全程閉環(huán),確保對方只處理一次。 -
通信流程
:4 步完成(“接收確認(rèn) - 釋放確認(rèn)”)
- 發(fā)送方發(fā)送 PUBLISH 報(bào)文(Dup=0,QoS=10,帶報(bào)文標(biāo)識符);
- 接收方收到后,暫存消息(不立即處理),并回復(fù)PUBREC 報(bào)文(確認(rèn) “已接收”,攜帶相同標(biāo)識符);
- 發(fā)送方收到 PUBREC 后,停止重發(fā) PUBLISH,發(fā)送PUBREL 報(bào)文(確認(rèn) “可釋放并處理消息”,標(biāo)識符不變);
- 接收方收到 PUBREL 后,處理暫存的消息,并回復(fù)PUBCOMP 報(bào)文(確認(rèn) “已處理完成”);
- 發(fā)送方收到 PUBCOMP 后,流程結(jié)束;若超時(shí)未收到,重發(fā) PUBREL(而非 PUBLISH)。
-
適用場景
對消息 “不丟失、不重復(fù)” 有嚴(yán)格要求的場景,如:
- 金融交易數(shù)據(jù)(如物聯(lián)網(wǎng)支付、設(shè)備計(jì)費(fèi));
- 醫(yī)療設(shè)備指令(如遠(yuǎn)程手術(shù)設(shè)備控制,重復(fù)執(zhí)行可能引發(fā)風(fēng)險(xiǎn))。
-
優(yōu)缺點(diǎn):
? 優(yōu)點(diǎn):最高可靠性,確保消息僅被處理一次;
? 缺點(diǎn):開銷最大(4 步通信、需暫存消息),不適合帶寬 / 資源極度受限的設(shè)備。
QoS 三個(gè)等級對比表
| 特性 | QoS 0(最多一次) | QoS 1(至少一次) | QoS 2(恰好一次) |
|---|---|---|---|
| 可靠性保證 | 可能丟失,不重復(fù) | 不丟失,可能重復(fù) | 不丟失,不重復(fù) |
| 通信步驟 | 1 步(無確認(rèn)) | 2 步(PUBLISH→PUBACK) | 4 步(PUBLISH→PUBREC→PUBREL→PUBCOMP) |
| 報(bào)文標(biāo)識符 | 不需要 | 需要(用于確認(rèn)) | 需要(用于多步確認(rèn)) |
| 消息暫存 | 不需要 | 發(fā)送方暫存(待確認(rèn)) | 發(fā)送方 + 接收方均暫存 |
| 帶寬 / 資源消耗 | 最低 | 中等 | 最高 |
| 典型應(yīng)用場景 | 實(shí)時(shí)傳感器數(shù)據(jù)、心跳 | 設(shè)備控制指令、關(guān)鍵上報(bào) | 金融交易、醫(yī)療指令 |
關(guān)鍵補(bǔ)充說明
- QoS 等級的協(xié)商:客戶端訂閱主題時(shí)會指定 “期望的 QoS”,服務(wù)端會根據(jù)自身能力(如是否支持該 QoS)返回 “實(shí)際的 QoS”(≤期望 QoS),最終以服務(wù)端確認(rèn)的 QoS 為準(zhǔn)。
- MQTT 版本差異:MQTT 5.0 在 3.1.1 的基礎(chǔ)上擴(kuò)展了 QoS 的 “屬性”(如消息過期時(shí)間、延遲發(fā)布),但核心的三個(gè) QoS 等級定義完全一致。
- 服務(wù)端角色:QoS 的實(shí)現(xiàn)依賴服務(wù)端的 “轉(zhuǎn)發(fā)邏輯”—— 例如,客戶端 A 以 QoS 1 發(fā)布消息到服務(wù)端,服務(wù)端會以 QoS 1 將消息轉(zhuǎn)發(fā)給訂閱的客戶端 B,并分別與 A、B 完成 QoS 1 的確認(rèn)流程。
主題(Topic)
主題是 MQTT 中用于定位消息流向的分層字符串,相當(dāng)于消息的 “郵箱地址”—— 發(fā)布者(Publisher)向指定主題 “投遞” 消息,訂閱者(Subscriber)通過訂閱主題 “接收” 對應(yīng)消息。主題本身不存儲消息,僅作為 “路由標(biāo)簽”。
主題的結(jié)構(gòu)規(guī)則
-
分層分隔符
使用
/分割主題的不同層級,形成樹形結(jié)構(gòu)(類似文件系統(tǒng)路徑),例如:sensor/temperature/room1(1 號房間的溫度傳感器)device/light/livingroom(客廳的燈光設(shè)備)
-
通配符支持
訂閱者可通過通配符訂閱多個(gè)關(guān)聯(lián)主題(發(fā)布者不能使用通配符發(fā)布消息),分為兩種:
單層通配符(+):匹配單個(gè)層級的任意字符(不能匹配多層或末尾無
/的主題)多層通配符(#):匹配當(dāng)前層級及以下所有層級(必須作為主題的最后一個(gè)字符)
通配符類型 符號 示例 匹配結(jié)果 單層通配符 +sensor/+/room1匹配 sensor/temperature/room1、sensor/humidity/room1;不匹配sensor/temperature/room1/window多層通配符 #sensor/temperature/#匹配 sensor/temperature/room1、sensor/temperature/room2/window、sensor/temperature(單層主題) -
禁止特殊字符:不能包含
\0(空字符),避免使用空格、#(非末尾)、+(非層級分隔)等,防止路由異常。 -
大小寫敏感:
Sensor/Temperature與sensor/temperature是兩個(gè)不同主題。
主題的常見設(shè)計(jì)范式
主題設(shè)計(jì)需兼顧 “靈活性” 與 “可維護(hù)性”,推薦按 “業(yè)務(wù)域 / 設(shè)備類型 / 設(shè)備 ID / 數(shù)據(jù)類型” 分層,例如:
- 設(shè)備狀態(tài)上報(bào):
device/{deviceType}/{deviceID}/state(如device/light/12345/state) - 控制指令下發(fā):
device/{deviceType}/{deviceID}/command(如device/fan/67890/command) - 全局廣播:
broadcast/all/notice(所有設(shè)備訂閱此主題接收通知)
消息(Message)
消息是 MQTT 中傳遞的實(shí)際數(shù)據(jù)內(nèi)容,由 “有效載荷(Payload)” 和 “消息屬性(Header)” 兩部分組成,設(shè)計(jì)上遵循 “輕量優(yōu)先” 原則,最小可僅包含 1 字節(jié)數(shù)據(jù)。
消息的核心組成
| 組成部分 | 說明 | 示例 |
|---|---|---|
| 有效載荷(Payload) | 實(shí)際傳遞的業(yè)務(wù)數(shù)據(jù),格式由業(yè)務(wù)自定義(如 JSON、二進(jìn)制、文本) | 溫度數(shù)據(jù):{"temp":25.3,"time":"2024-05-20 14:30"} |
| 消息屬性(Header) | 控制消息傳輸行為的元數(shù)據(jù),核心屬性包括: - QoS 等級:消息傳遞的可靠性級別 - Retain 標(biāo)志:是否在 Broker 端保留最新消息 - Duplicate 標(biāo)志:是否為重復(fù)發(fā)送的消息 | QoS=1,Retain=1(保留最新溫度值) |
關(guān)鍵消息屬性詳解
- QoS(Quality of Service)等級:MQTT 的核心可靠性機(jī)制,定義了 “發(fā)布者→Broker→訂閱者” 的消息傳遞保障。
- Retain 標(biāo)志:控制 Broker 是否 “緩存” 主題的最新消息。當(dāng) Retain=1 時(shí),Broker 會存儲該主題的最新消息;新訂閱者訂閱此主題時(shí),會直接收到 Broker 緩存的最新消息(無需等待發(fā)布者再次發(fā)送)。
示例:傳感器每小時(shí)上報(bào)一次溫度,設(shè)置 Retain=1 后,新接入的監(jiān)控平臺訂閱溫度主題時(shí),會立即獲取上一次的溫度值,無需等待 1 小時(shí)。 - Duplicate(Dup)標(biāo)志:僅在 QoS 1/2 中生效,標(biāo)識該消息是否為 “重發(fā)消息”(如 QoS 1 中發(fā)布者未收到 PUBACK 而重發(fā)),幫助訂閱者過濾重復(fù)數(shù)據(jù)。
訂閱(Subscription)
訂閱是訂閱者(如物聯(lián)網(wǎng)網(wǎng)關(guān)、手機(jī) APP、云平臺)向 MQTT Broker(消息代理服務(wù)器)發(fā)起的 “消息接收請求”—— 訂閱者通過指定 “主題(含通配符)” 和 “QoS 等級”,告知 Broker:“我需要接收該主題下,QoS 不超過 X 的所有消息”。
訂閱的核心機(jī)制
- 訂閱流程:訂閱者→Broker 發(fā)送
SUBSCRIBE請求(攜帶主題和訂閱 QoS)→Broker 驗(yàn)證通過后返回SUBACK確認(rèn)→訂閱生效,后續(xù)該主題的消息會被 Broker 主動推送給訂閱者。 - 訂閱 QoS 與消息 QoS 的關(guān)系:訂閱者設(shè)置的 QoS 是 “最大接收等級”,實(shí)際接收的消息 QoS 取 “發(fā)布者 QoS” 和 “訂閱 QoS” 的較小值。
示例:發(fā)布者以 QoS 2 發(fā)布消息,訂閱者以 QoS 1 訂閱,則訂閱者最終接收的消息 QoS 為 1(Broker 自動降級)。
訂閱的實(shí)踐要點(diǎn)
- 取消訂閱:訂閱者可通過發(fā)送
UNSUBSCRIBE請求取消訂閱,Broker 返回UNSUBACK確認(rèn)后,不再推送該主題的消息。 - 多訂閱者共享主題:同一主題可被多個(gè)訂閱者訂閱,Broker 會將消息復(fù)制并推送給所有訂閱者(Pub/Sub 模式的核心特性,實(shí)現(xiàn) “一對多” 通信)。
示例:3 個(gè)手機(jī) APP 同時(shí)訂閱device/light/livingroom/state,當(dāng)燈光狀態(tài)變化時(shí),3 個(gè) APP 會同時(shí)收到狀態(tài)更新消息。 - 訂閱權(quán)限控制:部分 Broker(如 EMQX、Mosquitto)支持 ACL(訪問控制列表),可限制訂閱者僅能訂閱指定主題(如禁止設(shè)備訂閱
broadcast/all全局主題),保障安全性。

浙公網(wǎng)安備 33010602011771號