文章目錄
- 什么是 MQTT?
- MQTT 的工作原理
- MQTT 客戶端
- MQTT Broker
- 發布-訂閱模式
- 主題
- QoS
- MQTT 的工作流程
- 開始使用 MQTT:快速教程
- 準備 MQTT Broker
- 準備 MQTT 客戶端
- 創建 MQTT 連接
- 通過通配符訂閱主題
- 發布 MQTT 消息
- MQTT 功能演示
- 保留消息
- Clean Session
- 遺囑消息

什么是 MQTT?
MQTT(Message Queuing Telemetry Transport)是一種輕量級、基于發布-訂閱模式的消息傳輸協議,適用于資源受限的設備和低帶寬、高延遲或不穩定的網絡環境。它在物聯網應用中廣受歡迎,能夠實現傳感器、執行器和其它設備之間的高效通信。
MQTT 的工作原理
要了解 MQTT 的工作原理,首先需要掌握以下幾個概念:MQTT 客戶端、MQTT Broker、發布-訂閱模式、主題、QoS。
MQTT 客戶端
任何運行 MQTT 客戶端庫的應用或設備都是 MQTT 客戶端。例如,使用 MQTT 的即時通訊應用是客戶端,使用 MQTT 上報數據的各種傳感器是客戶端,各種 MQTT 測試工具也是客戶端。
MQTT Broker
MQTT Broker 是負責處理客戶端請求的關鍵組件,包括建立連接、斷開連接、訂閱和取消訂閱等操作,同時還負責消息的轉發。一個高效強大的 MQTT Broker 能夠輕松應對海量連接和百萬級消息吞吐量,從而幫助物聯網服務提供商專注于業務發展,快速構建可靠的 MQTT 應用。
發布-訂閱模式
發布-訂閱模式與客戶端-服務器模式的不同之處在于,它將發送消息的客戶端(發布者)和接收消息的客戶端(訂閱者)進行了解耦。發布者和訂閱者之間無需建立直接連接,而是通過 MQTT Broker 來負責消息的路由和分發。
下圖展示了 MQTT 發布/訂閱過程。溫度傳感器作為客戶端連接到 MQTT Broker,并通過發布操作將溫度數據發布到一個特定主題(例如 Temperature)。MQTT Broker 接收到該消息后會負責將其轉發給訂閱了相應主題(Temperature)的訂閱者客戶端。
主題
MQTT 協議根據主題來轉發消息。主題通過 / 來區分層級,類似于 URL 路徑,例如:
chat/room/1sensor/10/temperaturesensor/+/temperature
MQTT 主題支持以下兩種通配符:+ 和 #。
- +:表示單層通配符,例如 a/+ 匹配 a/x 或 a/y。
- #:表示多層通配符,例如 a/# 匹配 a/x、a/b/c/d。
注意:通配符主題只能用于訂閱,不能用于發布。
QoS
MQTT 提供了三種服務質量(QoS),在不同網絡環境下保證消息的可靠性。
- QoS 0:消息最多傳送一次。如果當前客戶端不可用,它將丟失這條消息。
- QoS 1:消息至少傳送一次。
- QoS 2:消息只傳送一次。
MQTT 的工作流程
在了解了 MQTT 的基本組件之后,讓我們來看看它的一般工作流程:
- 客戶端使用 TCP/IP 協議與 Broker 建立連接,可以選擇使用 TLS/SSL 加密來實現安全通信。客戶端提供認證信息,并指定會話類型(Clean Session 或 Persistent Session)。
- 客戶端既可以向特定主題發布消息,也可以訂閱主題以接收消息。當客戶端發布消息時,它會將消息發送給 MQTT Broker;而當客戶端訂閱消息時,它會接收與訂閱主題相關的消息。
- MQTT Broker 接收發布的消息,并將這些消息轉發給訂閱了對應主題的客戶端。它根據 QoS 等級確保消息可靠傳遞,并根據會話類型為斷開連接的客戶端存儲消息。
開始使用 MQTT:快速教程
下面我們將通過一些簡單的示例來展示如何使用 MQTT。在開始之前,需要準備 MQTT Broker 和 MQTT 客戶端。
準備 MQTT Broker
您可以選擇私有部署或完全托管的云服務來建立自己的 MQTT Broker。或者您也可以使用免費的公共 Broker。
- 私有部署
EMQX 是最具擴展性的開源 MQTT Broker,適用于物聯網、工業物聯網和車聯網。您可以運行以下 Docker 命令來安裝 EMQX。
docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx
- 全托管的云服務
通過全托管的云服務啟動 MQTT 服務是最便捷的方式。如下圖所示,EMQX Cloud 可以在幾分鐘內啟動,并在 AWS、Google Cloud 和 Microsoft Azure 的 17 個區域提供運行支持。
- 免費的公共 MQTT Broker
在本文中,我們將使用 EMQ 提供的免費公共 MQTT Broker,它基于完全托管的 MQTT 云服務 - EMQX Cloud 創建。服務器信息如下:
Server: broker.emqx.ioTCP Port: 1883WebSocket Port: 8083SSL/TLS Port: 8883Secure WebSocket Port: 8084
準備 MQTT 客戶端
在本文中,我們將使用 MQTTX 提供的支持瀏覽器訪問的 MQTT 客戶端工具,訪問地址為 http://www.emqx.io/online-mqtt-client 。 MQTTX 還提供了桌面客戶端和命令行工具。
MQTTX 是一款跨平臺的 MQTT 5.0 桌面客戶端,可在 macOS、Linux、Windows 操作系統上運行。其用戶友好的聊天式界面使用戶能夠輕松創建多個 MQTT/MQTTS 連接,并進行 MQTT 消息的訂閱和發布。
目前,各種編程語言都擁有成熟的開源 MQTT 客戶端庫。我們在流行的 MQTT 客戶端庫和 SDK 中精選了多個編程語言的 MQTT 客戶端庫,并提供了詳細的代碼示例,旨在幫助您快速了解 MQTT 客戶端的使用。
創建 MQTT 連接
在使用 MQTT 協議進行通信之前,客戶端需要創建一個 MQTT 連接來連接到 Broker。
在瀏覽器中打開 http://www.emqx.io/online-mqtt-client , 點擊頁面中間的 New Connection
按鈕,將看到如下頁面。
我們在 Name 中輸入 Simple Demo,然后點擊右上角的 Connect 按鈕,建立一個 MQTT 連接。如下圖所示,表示連接成功。
通過通配符訂閱主題
接下來,我們在上面創建的 Simple Demo
連接中通過通配符訂閱主題 sensor/+/temperature
,這樣就可以接收所有傳感器發送的溫度數據了。
如下圖所示,點擊 New Subscription
按鈕,在彈出框中的 Topic
字段中輸入主題 sensor/+/temperature
,QoS 保持默認值 0。
訂閱成功后,會在訂閱列表的中間看到新增了一條記錄。
發布 MQTT 消息
接下來,我們點擊左側菜單上的 +
按鈕創建兩個連接,分別命名為 Sensor 1
和 Sensor 2
,用來模擬兩個溫度傳感器。
連接創建成功后,會看到三個連接,每個連接左側的在線狀態指示燈都是綠色的。
選擇 Sensor 1
連接,在頁面下方的發布主題中輸入 sensor/1/temperature
,在消息框中輸入以下 JSON 格式的消息,然后點擊右下方的發布按鈕發送消息。
{"msg": "17.2"
}
如下圖所示,消息發送成功。
使用相同的步驟,在 Sensor 2
連接中發布以下 JSON 消息到 sensor/2/temperature
主題。
{"msg": "18.2"
}
您會看到 Simple Demo 連接收到兩條新消息。
點擊 Simple Demo 連接,會看到兩個傳感器發送的兩條消息。
MQTT 功能演示
保留消息
當 MQTT 客戶端向服務器發布消息時,可以設置保留消息標志。保留消息存儲在消息服務器上,后續訂閱該主題的客戶端仍然可以收到該消息。
如下圖所示,我們在 Sensor 1
連接中勾選 Retain
選項,然后向 retained_message
主題發送兩條消息。
接著,我們在 Simple Demo
連接中訂閱 retained_message
主題。訂閱成功后,會收到 Sensor 1
發送的第二條保留消息,這說明服務器只會為主題保留最近的一條保留消息。
Clean Session
MQTT 客戶端通常只能在在線狀態下接收其它客戶端發布的消息。如果客戶端離線后重新上線,它將無法收到離線期間的消息。
但是,如果客戶端連接時設置 Clean Session 為 false,并且使用相同的客戶端 ID 再次上線,那么消息服務器將為客戶端緩存一定數量的離線消息,并在它重新上線時發送給它。
本次演示使用的公共 MQTT 服務器設置為緩存 5 分鐘的離線消息,最大消息數為 1000 條,且不保存 QoS 0 消息。
下面,我們創建一個 MQTT 3.1.1 連接,并用 QoS 1 來演示 Clean Session 的使用。
MQTT 5.0 中將 Clean Session 拆分成了 Clean Start 與 Session Expiry Interval。
創建一個名為 MQTT V3
的連接,設置 Clean Session 為 false,選擇 MQTT 版本為 3.1.1。
連接成功后,訂閱 clean_session_false
主題,并將 QoS 設置為 1。
訂閱成功后,點擊右上角的斷開按鈕,斷開連接。
然后,創建一個名為 MQTT_V3_Publish
的連接,MQTT 版本也設置為 3.1.1。連接成功后,向 clean_session_false
主題發布三條消息。
接著,選擇 MQTT_V3
連接,點擊連接按鈕重新連接到服務器,會收到三條離線消息。
遺囑消息
MQTT 客戶端在向服務器發起 CONNECT 請求時,可以選擇是否發送遺囑消息標志,并指定遺囑消息的主題和有效載荷。
如果 MQTT 客戶端異常離線(在斷開連接前沒有向服務器發送 DISCONNECT 消息),MQTT 服務器會發布遺囑消息。
我們創建一個名為 Last Will
的連接來演示這個功能。為了快速看到效果,我們把 Keep Alive 設置為 5 秒。
- Last-Will Topic 設置為
last_will
。 - Last-Will QoS 設置為
1
。 - Last-Will Retain 設置為
true
。 - Last-Will Payload 設置為
offline
。
連接成功后,我們斷開電腦網絡超過 5 秒(模擬客戶端異常斷開連接),然后再恢復網絡。
接著啟動 Simple Demo 連接,并訂閱 last_will
主題。您會收到 Last Will 連接設置的遺囑消息。
本文詳細介紹了 MQTT 的基本概念和使用流程,您可以按照本文所學的內容嘗試使用 MQTT 協議。