解鎖 MQTT Wildcards ( 通配符 )的力量 | 深入解析 + 和 #
在物聯網(IoT)領域中,MQTT(消息隊列遙測傳輸)作為一種輕量級的消息傳遞協議,廣泛應用於各種設備之間的通信。它基於 發布/訂閱模式,利用主題(Topic)來組織消息流。對開發者而言,主題的設計和訂閱模式至關重要,這裡的 MQTT Wildcards (通配符) 起到了極其重要的作用。
如果你曾經在 MQTT 中處理過主題訂閱,你就會知道,訂閱某一個特定主題可能會變得繁瑣,尤其當你的系統有很多變量和層級時。這時,通配符就成為了強大的工具,幫助你簡化主題訂閱,讓你的系統變得更加靈活且易於擴展。
內容
什麼是 MQTT Wildcards (通配符)
在 MQTT 中,主題 是用來標識訊息流的“地址”。每個設備、感測器或應用程式都會根據特定的主題來發送或接收消息。然而,有時候你並不想訂閱某一個具體的主題,而是希望接收符合某些模式的多個主題。這時候,通配符就派上用場了。
MQTT Wildcards (通配符) 允許你在訂閱時匹配多個主題,這不僅能讓你減少訂閱的數量,還能增強系統的可擴展性和靈活性。MQTT 支援兩種常用的通配符:單層通配符(+
) 和 多層通配符(#
)。
通配符的詳細解析
單層通配符 +
+
是一個單層 MQTT Wildcard (通配符),它能夠匹配主題中的任意一層,但只限於單層。如果主題結構中有多層,+
只能匹配一層,不能跨層匹配。
假設你的主題結構如下:
home/livingroom/temperature
home/kitchen/temperature
home/livingroom/humidity
如果你訂閱 home/+/temperature
,你會收到以下消息:
home/livingroom/temperature
home/kitchen/temperature
但 home/livingroom/humidity
不會匹配,因為 +
只會匹配 temperature
層級,並且無法跨越子層。
使用場景 :
- 當你想要訂閱某一層級的所有子主題時,可以使用
+
來代替具體的層級。 - 例如,在家庭自動化系統中,你可以訂閱
home/+/temperature
,這樣你就能接收到每個房間的溫度數據,而不需要為每個房間分別訂閱。
多層通配符 #
#
是一個多層 MQTT Wildcard (通配符),能夠匹配任意層級的所有子層級。這是 MQTT 中最強大的通配符,尤其在有大量設備或多層級主題結構時,能夠顯著簡化訂閱過程。#
只能出現在主題的結尾,如果出現在其他位置,訂閱會失敗。
假設你的主題結構如下:
home/livingroom/temperature
home/kitchen/temperature
home/livingroom/temperature/room1
home/livingroom/humidity
如果你訂閱 home/#
,你將會收到:
home/livingroom/temperature
home/kitchen/temperature
home/livingroom/temperature/room1
home/livingroom/humidity
這是因為 #
匹配了 home/
後的所有子主題。
使用場景 :
- 當你希望接收某個範圍內的所有消息時,
#
是理想的選擇。比如你有很多房間,並希望接收所有房間的數據,可以訂閱home/#
,這樣不管有多少房間,所有以home/
開頭的數據都會自動進來。
表格說明 +
和 #
的區別
特性 | 單層 MQTT Wildcard (通配符) + | 多層 MQTT Wildcard (通配符) # |
---|---|---|
匹配範圍 | 只能匹配一層 | 匹配從指定層級開始的所有層級 |
位置限制 | 可以出現在主題的任何層級 | 只能出現在主題的末尾 |
典型用法 | 當你只關心某一層級時 | 當你需要訂閱多層級時 |
如何在 MQTT 中使用這些通配符
讓我們來看看如何使用 Python 客戶端來訂閱帶有通配符的主題。這裡我們使用 paho-mqtt 庫來實現。
首先,安裝 paho-mqtt
客戶端庫
pip install paho-mqtt
範例代碼
import paho.mqtt.client as mqtt
import warnings
# Disable DeprecationWarnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
# Set the MQTT broker address (using HiveMQ broker)
broker = "broker.hivemq.com"
# Set the topic to subscribe to
topic = "home/+/temperature"
# Callback function that gets triggered when a message is received
def on_message(client, userdata, message):
# Decode the payload (message content)
payload = message.payload.decode()
print(f"Received message: {payload}")
# If the message contains 'Temperature', extract and print the temperature value
if "Temperature" in payload:
# Extract the numeric part of the temperature (e.g., "23°C")
temperature = float(payload.split(":")[1].strip().replace("°C", ""))
print(f"Temperature value: {temperature}°C")
# If the message is a numeric value (e.g., 29.60), process it
elif payload.replace(".", "", 1).isdigit():
value = float(payload) # Convert the string to a float
print(f"Numeric value: {value}")
# If the message does not match any expected pattern
else:
print("Received message in unexpected format")
# Create an MQTT client instance
client = mqtt.Client(client_id="pythonClient", protocol=mqtt.MQTTv5)
client.on_message = on_message # Assign the callback function to handle incoming messages
# Connect to the MQTT broker
client.connect(broker)
# Subscribe to the topic with a wildcard to capture all temperature readings
client.subscribe(topic)
# Keep the client running to wait for messages
client.loop_forever()
程式碼說明
warnings.filterwarnings("ignore", category=DeprecationWarning)
:這一行用來忽略 DeprecationWarning 警告訊息,防止它在控制台中列印。
on_message
回呼函数:這個回呼函數會在接收到MQTT 訊息時觸發,它首先列印接收到的訊息內容,如果訊息包含Temperature 字串,它會提取出溫度資料(假設訊息格式為Temperature: 23°C),如果訊息是一個數字(如29.60),則將其作為浮動數值處理,並可以在else 中加入更多的邏輯來處理其他類型的訊息。
client.connect(broker)
:連接到指定的 MQTT 伺服器。
client.subscribe(topic)
:訂閱一個或多個主題。在這個範例中,使用了一個有萬用字元的主題 “home/+/temperature”,這表示訂閱所有 “home/裝置類型/temperature” 格式的主題。
client.loop_forever()
:啟動 MQTT 用戶端的迴圈,使其能夠持續接收並處理訊息。
輸出
假設 MQTT 伺服器發布瞭如下訊息:
"Temperature: 23°C"
"29.60"
"2"
運行時的輸出將類似於:
Received message: Temperature: 23°C
Temperature value: 23.0°C
Received message: 29.60
Numeric value: 29.6
Received message: 2
Numeric value: 2.0
為什麼使用通配符
- 減少訂閱數量
通配符讓你可以在不需要精確指定每個設備的情況下,簡化訂閱過程。你只需要訂閱更高層級的主題,就能接收到來自不同設備的消息。 - 提高靈活性
隨著系統的擴展,傳統的手動訂閱方法可能會變得冗長且難以管理。而使用通配符,你可以更輕鬆地處理不同層級的消息流,避免硬編碼每個設備的主題。 - 提升可維護性
通配符使得在需要添加新的設備或新的功能時,無需更改訂閱邏輯。只需確保新設備的主題結構符合已有的規範即可。
智能家居系統
假設你有一個智能家居系統,涉及多個房間,每個房間有不同的感測器,如溫度、濕度、光線等。傳統方法會讓你為每個房間的每個感測器分別訂閱主題,這會造成訂閱數量激增,並難以維護。使用 MQTT Wildcards (通配符) 後,你只需要訂閱:
home/+/temperature
:接收所有房間的溫度數據。home/#
:接收所有房間的所有數據(溫度、濕度等)。
這樣,你的訂閱就變得更簡單,且能輕鬆應對新的房間或設備。
結論
MQTT 的 **通配符** 功能是開發者在構建物聯網系統時不可或缺的工具。無論是單層 MQTT Wildcard (通配符) +
還是多層 MQTT Wildcard (通配符) #
,它們都能幫助你簡化訂閱邏輯,提升系統的靈活性和可擴展性。理解和合理使用這些 MQTT Wildcards (通配符),可以大大提高開發效率,並為未來的擴展和維護奠定堅實基礎。
希望這篇文章能夠幫助你更好地理解和使用 MQTT 的 MQTT Wildcards (通配符),並提升你在物聯網開發中的能力!