2024年8月12日 星期一

MQTT 協議入門:基礎知識和快速教程

 

MQTT 協議入門:基礎知識和快速教程

https://www.emqx.com/zh/blog/the-easiest-guide-to-getting-started-with-mqtt
EMQX Team
2022-9-9
MQTT 協議入門:基礎知識和快速教程

本文是MQTT 協議的入門指南,提供了實用的程式碼範例。物聯網和MQTT 的初學者可以透過本文掌握MQTT 的基本概念,快速開啟MQTT 服務和應用的開發。

什麼是MQTT?

MQTT(Message Queuing Telemetry Transport)是一種輕量級、基於發布-訂閱模式的訊息傳輸協議,適用於資源受限的裝置和低頻寬、高延遲或不穩定的網路環境。它在物聯網應用中廣受歡迎,能夠實現感測器、執行器和其它設備之間的高效通訊。

為什麼MQTT 是適用於物聯網的最佳協定?

MQTT 所具有的適用於物聯網特定需求的特性和功能,使其成為物聯網領域最佳的協定之一。它的主要特點包括:

  • 輕量級:物聯網設備通常在處理能力、記憶體和能耗方面受到限制。 MQTT 開銷低、報文小的特點使其非常適合這些設備,因為它消耗更少的資源,即使在有限的能力下也能實現高效的通訊。
  • 可靠:物聯網網路常常面臨高延遲或連線不穩定的情況。 MQTT 支援多種QoS 等級、會話感知和持久連接,即使在困難的條件下也能保證訊息的可靠傳遞,使其非常適合物聯網應用。
  • 安全通訊:安全對於物聯網網路至關重要,因為其經常涉及敏感資料的傳輸。為確保資料在傳輸過程中的機密性,MQTT 提供傳輸層安全性(TLS)和安全通訊端層(SSL)加密功能。此外,MQTT 還透過使用者名稱/密碼憑證或用戶端憑證提供身份驗證和授權機制,以保護網路及其資源的存取。
  • 雙向通訊: MQTT 的發布-訂閱模式為設備之間提供了無縫的雙向通訊方式。客戶端既可以向主題發布訊息,也可以訂閱接收特定主題上的訊息,從而實現了物聯網生態系統中的高效資料交換,而無需直接將設備耦合在一起。這種模式也簡化了新設備的集成,同時確保了系統易於擴展。
  • 連續、有狀態的會話: MQTT 提供了客戶端與Broker 之間保持有狀態會話的能力,這使得系統即使在斷開連接後也能記住訂閱和未傳遞的訊息。此外,用戶端還可以在建立連線時指定保活間隔,這會促使Broker 定期檢查連線狀態。如果連線中斷,Broker 會儲存未傳遞的訊息(根據QoS 等級決定),並在用戶端重新連線時嘗試傳遞它們。這個特性保證了通訊的可靠性,降低了因間斷性連接而導致資料遺失的風險。
  • 大規模物聯網設備支援:物聯網系統往往涉及大量設備,需要一種能夠處理大規模部署的協定。 MQTT 的輕量級特性、低頻寬消耗和對資源的高效利用使其成為大規模物聯網應用的理想選擇。透過採用發布-訂閱模式,MQTT 實現了發送者和接收者的解耦,從而有效地減少了網路流量和資源使用。此外,協議對不同QoS 等級的支援使得訊息傳遞可以根據需求進行定制,確保在各種場景下獲得最佳的效能表現。
  • 語言支援:物聯網系統包含使用各種程式語言開發的設備和應用。 MQTT 具有廣泛的語言支持,使其能夠輕鬆與多個平台和技術進行集成,從而實現了物聯網生態系統中的無縫通訊和互通性。您可以閱讀我們的MQTT 用戶端程式設計系列文章,學習如何在PHP、Node.js、Python、Golang、Node.js 等程式語言中使用MQTT。

MQTT 的工作原理

要了解MQTT 的工作原理,首先需要掌握以下幾個概念:MQTT 用戶端、MQTT Broker、發布-訂閱模式、主題、QoS。

MQTT 用戶端

任何運行MQTT 客戶端程式庫的應用程式或裝置都是MQTT 用戶端。例如,使用MQTT 的即時通訊應用是客戶端,使用MQTT 上報資料的各種感測器是客戶端,各種MQTT 測試工具也是客戶端。

MQTT Broker

MQTT Broker 是負責處理客戶端要求的關鍵元件,包括建立連線、斷開連線、訂閱和取消訂閱等操作,同時也負責訊息的轉送。一個高效強大的MQTT Broker 能夠輕鬆應對海量連接和百萬級訊息吞吐量,從而幫助物聯網服務供應商專注於業務發展,快速建立可靠的MQTT 應用。

關於MQTT Broker 的更多詳情,請參閱文章2023 年最全面的MQTT Broker 比較指南

發布-訂閱模式

發布-訂閱模式與客戶端-伺服器模式的不同之處在於,它將發送訊息的客戶端(發布者)和接收訊息的客戶端(訂閱者)進行了解耦。發布者和訂閱者之間無需建立直接連接,而是透過MQTT Broker 來負責訊息的路由和分發。

下圖展示了MQTT 發布/訂閱流程。溫度感測器作為客戶端連接到MQTT Broker,並透過發布操作將溫度資料發佈到一個特定主題(例如Temperature)。 MQTT Broker 接收到該訊息後會負責將其轉發給訂閱了對應主題(Temperature)的訂閱者用戶端。

MQTT 發布-訂閱模式

主題

MQTT 協議根據主題來轉發訊息。主題透過/來區分層級,類似URL 路徑,例如:

chat /room/ 1

sensor /10/ temperature

sensor /+/ temperature

MQTT 主題支援以下兩種通配符:+#

  • +:表示單層通配符,例如a/+匹配a/xa/y
  • #:表示多層通配符,例如a/#匹配a/xa/b/c/d

注意:通配符主題只能用於訂閱,不能用於發布。

關於MQTT 主題的更多詳情,請參閱文章透過案例理解MQTT 主題與通配符

QoS

MQTT 提供了三種服務品質(QoS),在不同網路環境下保證訊息的可靠性。

  • QoS 0:訊息最多傳送一次。如果當前客戶端不可用,它將丟失這條訊息。
  • QoS 1:訊息至少傳送一次。
  • QoS 2:訊息只會傳送一次。

關於MQTT QoS 的更多詳情,請參閱文章MQTT QoS 0, 1, 2 介紹

MQTT 的工作流程

在了解了MQTT 的基本組件之後,讓我們來看看它的一般工作流程:

  1. 用戶端使用TCP/IP 協定與Broker 建立連接,可選擇使用TLS/SSL 加密來實現安全通訊。用戶端提供認證訊息,並指定會話類型(Clean Session 或Persistent Session)。
  2. 客戶端既可以向特定主題發布訊息,也可以訂閱主題以接收訊息。當客戶端發布訊息時,它會將訊息傳送給MQTT Broker;而當客戶端訂閱訊息時,它會接收與訂閱主題相關的訊息。
  3. 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/emem
    
  • 全託管的雲端服務

    透過全託管的雲端服務啟動MQTT 服務是最方便的方式。如下圖所示,EMQX Cloud可以在幾分鐘內啟動,並在AWS、Google Cloud 和Microsoft Azure 的17 個區域提供運作支援。

    EMQX MQTT Cloud

  • 免費的公共MQTT Broker

    在本文中,我們將使用EMQ 提供的免費公共MQTT Broker,它是基於完全託管的MQTT 雲端服務- EMQX Cloud創建。伺服器資訊如下:

    Server:broker.emqx.io

    TCP Port:1883

    WebSocket Port:8083

    SSL/TLS Port:8883

    Secure WebSocket Port:8084

準備MQTT 用戶端

在本文中,我們將使用MQTTX提供的支援瀏覽器存取的MQTT 用戶端工具,存取位址為http://mqtt-client.emqx.com/。 MQTTX 也提供了桌面用戶端命令列工具

MQTTX是一款跨平台的MQTT 5.0 桌面用戶端,可在macOS、Linux、Windows 作業系統上運作。其用戶友好的聊天式介面使用戶能夠輕鬆創建多個MQTT/MQTTS 連接,並進行MQTT 訊息的訂閱和發布。

MQTTX

MQTTX 介面

目前,各種程式語言都擁有成熟的開源MQTT 用戶端程式庫。我們在流行的MQTT 用戶端庫和SDK中精選了多個程式語言的MQTT 用戶端程式庫,並提供了詳細的程式碼範例,旨在幫助您快速了解MQTT 用戶端的使用。

建立MQTT 連接

在使用MQTT 協定進行通訊之前,客戶端需要建立一個MQTT 連線來連接到Broker。

在瀏覽器中開啟http://mqtt-client.emqx.com/ , 點選頁面中間的New Connection按鈕,將會看到以下頁面。

建立MQTT 連接

我們在Name中輸入Simple Demo,然後點擊右上角的Connect按鈕,建立一個MQTT 連線。如下圖所示,表示連線成功。

MQTT 連結成功

若要了解更多關於MQTT 連線參數的內容,請查看我們的文章:建立MQTT 連線時如何設定參數

透過通配符訂閱主題

接下來,我們在上面創建的Simple Demo連接中透過通配符訂閱主題sensor/+/temperature,這樣就可以接收所有感測器發送的溫度資料了。

如下圖所示,點選New Subscription按鈕,在彈出框中的Topic欄位中輸入主題sensor/+/temperature,QoS 保持預設值0。

訂閱MQTT 通配符主題

訂閱成功後,會在訂閱清單的中間看到新增了一筆記錄。

MQTT 主題訂閱成功

發布MQTT 訊息

接下來,我們點擊左側選單上的+按鈕建立兩個連接,分別命名為Sensor 1Sensor 2,用來模擬兩個溫度感測器。

建立MQTT 連接

連接建立成功後,會看到三個連接,每個連接左側的在線狀態指示燈都是綠色的。

三個連接創建成功

選擇Sensor 1連接,在頁面下方的發布主題中輸入sensor/1/temperature,在訊息框中輸入以下JSON 格式的訊息,然後點擊右下方的發布按鈕發送訊息。

{ 
  "msg" :  "17.2" 
}

發布MQTT 訊息

如下圖所示,訊息發送成功。

MQTT 訊息發布成功

使用相同的步驟,在Sensor 2連線中發布以下JSON 訊息到sensor/2/temperature主題。

{ 
  "msg" :  "18.2" 
}

您會看到Simple Demo連線收到兩個新訊息。

2條訊息提示

點擊Simple Demo連接,會看到兩個感測器發送的兩個訊息。

查看訊息詳情

MQTT 功能演示

保留訊息

當MQTT 用戶端向伺服器發布訊息時,可以設定保留訊息標誌。保留訊息儲存在訊息伺服器上,後續訂閱該主題的用戶端仍可收到該訊息。

如下圖所示,我們在Sensor 1連線中勾選Retain選項,然後向retained_message主題發送兩個訊息。

MQTT Retain

接著,我們在Simple Demo連線中訂閱retained_message主題。訂閱成功後,會收到Sensor 1傳送的第二個保留訊息,這表示伺服器只會為主題保留最近的一條保留訊息。

MQTT 保留訊息

關於保留訊息的更多細節,請閱讀文章MQTT 保留訊息初學者指南

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。詳情請參考文章Clean Start 與Session Expiry Interval

建立名為MQTT V3的連接,設定Clean Session 為false,選擇MQTT 版本為3.1.1。

設定Clean Session 為false

連線成功後,訂閱clean_session_false主題,並將QoS 設定為1。

訂閱clean_session_false 主題

訂閱成功後,點選右上角的斷開按鈕,斷開連線。

斷開MQTT 連接

然後,建立一個名為MQTT_V3_Publish的連接,MQTT 版本也設定為3.1.1。連線成功後,向clean_session_false主題發布三條訊息。

建立一個名為MQTT_V3_Publish 的連接

接著,選擇MQTT_V3連接,點選連接按鈕重新連接到伺服器,會收到三條離線訊息。

接收三條離線訊息

關於Clean Session 的更多細節,請閱讀文章MQTT Persistent Session 與Clean Session 詳解

遺囑消息

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

建立名為Last Will 的連接

連線成功後,我們斷開電腦網路超過5 秒(模擬客戶端異常斷開連線),然後再恢復網路。

接著啟動Simple Demo 連接,並訂閱last_will主題。您會收到Last Will連接設定的遺囑訊息。

收到Last Will 連線設定的遺囑訊息

關於MQTT 遺囑訊息的更多內容,請閱讀文章MQTT 遺囑訊息的使用

深入學習MQTT

本文詳細介紹了MQTT 的基本概念和使用流程,您可以按照本文所學的內容嘗試使用MQTT 協定。

如果您想了解更多MQTT 的知識,建議您閱讀EMQ 提供的MQTT 教學:從入門到精通系列文章,了解MQTT 主題、通配符、保留訊息、遺囑訊息等功能。透過這些文章,您將能夠探索MQTT 的更高級應用場景,並開始進行MQTT 應用和服務的開發。

沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...