iT邦幫忙

2024 iThome 鐵人賽

DAY 20
1

工作前其實完全沒有聽過 MQTT,後來用到才開始了解他,今天來用最簡單的方式,介紹一下什麼是 MQTT !

What is MQTT?

https://ithelp.ithome.com.tw/upload/images/20241003/20150927hRsRgAfvtl.png
MQTT is a lightweight, publish-subscribe, machine to machine network protocol for message queue/message queuing service.
MQTT 是一個輕量且可靠的二進位通訊協定,專門為需要節省網路資源的應用場景所設計。它和 HTTP 一樣,底層都是 TCP/IP,只是訊息的格式不太一樣。

它採用發布-訂閱(Pub-Sub)模式。這個模式不需要發送者與接收者直接連接,所有的訊息都透過**中央的 Broker **來管理。由於網路資源需求較低、高效率的特性,MQTT 成為物聯網(IoT)設備間常用的協議。

雖然常用於 IOT 但在需要低延遲的產品上也能使用,如 Facebook Messenger 這樣的即時通訊的軟體,因為它能在大規模的使用者基礎上提供低延遲的通訊,並且有效減少網路資源的消耗。所以也使用 MQTT。

發布 / 訂閱( Publish / Subscribe )模式

MQTT 採用的架構是 Client(客戶端)和 Broker(代理服務器)。客戶端負責發佈或訂閱訊息,Broker 負責接收和發布的訊息。
https://ithelp.ithome.com.tw/upload/images/20241003/20150927atSAr4dus8.png
圖片來源

訊息格式

https://ithelp.ithome.com.tw/upload/images/20241003/20150927qeiOrTVxPu.png
圖片來源

  • Fixed Header
    • Control Packet Type:包含 4 位元表示訊息的類型,如發布 (PUBLISH)、訂閱 (SUBSCRIBE) 等。
    • Flags:一些負責控制的資訊,例如 DUP (Duplicate Delivery)、QoS 等級、Retain 的 flag 等。
    • Remaining Length:一些剩餘可變的資訊。如 variable header 和 payload。
  • Variable Header
    • 根據不同的 MQTT 訊息類型,可能有不同的欄位。例如在 PUBLISH 訊息中,會包含主題名稱 (Topic Name) 和封包識別碼 (Packet Identifier)。
  • Payload
    • 訊息實際的內容。

Topic

每個 MQTT 訊息都會有一個主題,可以透過訂閱/發布主題,來進行訊息的交流。
主題可以有不同的階層架構,如檔案路徑一般用 / 來做階層的區隔。

/vehicle/car/wheel #交通工具/汽車/輪子
/university/department #大學/系所

Quality Of Service(QOS)

  • QoS level
    • QoS 0:最多傳一次(At most once)

      • 提供最低限度的傳輸。在 QOS 0,每條訊息只會傳送一次,他不會進行驗證,無法確認接收者是否收到訊息。這種策略通常被稱為「即發即忘」(Fire and forget)或「 At most once 」。訊息在斷線後重新連接也不會儲存。
    • QoS 1:至少傳一次(At least once)

      • Broker 會嘗試傳送訊息,並等待接收者的確認回覆。如果在設定的時間內沒有收到確認,訊息將被重新傳送。這意味著如果 Broker 沒有及時收到確認,訊息可能會被傳送多次,因此被稱為「 At least once 」。
    • QoS 2:確實傳一次(Exactly once)

      • 客戶端和 Broker 之間會進行四次握手,確保訊息被完整接收且只接收一次。這種策略有時被稱為「恰好傳送一次」。

當網路資源有限時,QoS 0 可能是最佳選擇;而當通訊不穩定但資源較充足時,QoS 2 是最理想的選擇。

Retained Messages

保留訊息(Retained Messages):保留訊息會保存最後 PUBLISH 的訊息,如果使用者斷線或有新的訂閱者就可以立即接收到最新的消息。

Python paho-mqtt

簡單用 Python 建立一個 MQTT

import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print(f"Connected with result code {rc}")
    client.subscribe("sensor/temperature")

def on_message(client, userdata, msg):
    print(f"{msg.topic} {msg.payload.decode()}")

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.connect("mqtt-broker.example.com", 1883, 60) #port 預設 1883 
client.loop_forever()

Reference


上一篇
Day-19 | ORM & N+1 problem
下一篇
Day-21 | Message Queue - RabbitMQ
系列文
埋藏在後端工程下的地雷與寶藏30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言