MQTT-SN 全名為 MQTT for Sensor Networks,其目標是為非 TCP/IP 協議棧的嵌入式設備(如 Zigbee、Bluetooth)提供應用層通信標準。MQTT-SN 是一個專為 WSN(Wireless Sensor Networks)網絡設計的 Publish/Subscribe 的消息傳輸協議。
大規模分佈式物聯網 MQTT 消息服務器 EMQX 除了完整支持 MQTT 協議外,還可以通過網關處理所有非 MQTT 協議的連接、認證和消息收發,併為其提供統一的用户層接口。本文將介紹如何在 EMQX 中接入 MQTT-SN 協議設備,並通過認證及授權保障設備接入安全。
MQTT-SN 的優點是什麼?
- 與 MQTT 協議兼容: MQTT-SN 通信模型完全與 MQTT 相對應,例如發佈、訂閲、保留會話、遺囑消息等。統一的模型有利於降低端到端的設計複雜度。
- 輕量: 為了應對 WSN 網絡中有限的傳輸帶寬,協議設計非常精簡。例如 PUBLISH 消息中的主題名稱被一個短的、兩字節長的 Topic ID 取代。
- 支持休眠: MQTT-SN 協議新增了休眠邏輯,來應對低功耗的場景。例如設備進入到休眠後,所有發給它們的消息都會被緩存在服務器,並在喚醒後傳遞給它們。
MQTT-SN 常見的部署結構
- Client 和 Gateway 部署在同一個局域網中(例如 Zigbee)通過 MQTT-SN 協議進行通信,並且 Gateway 通過以太網和 MQTT 協議將數據上報到雲端的 MQTT Broker。
- MQTT Broker 與 MQTT-SN Gateway 集成在一起,都部署在雲端。Client 通過 UDP 和 MQTT-SN 直接與雲端的 MQTT-SN 網關進行通信。
- 第三種部署方式與第一種類似,不同的是使用 MQTT-SN 協議與雲端的 MQTT-SN 網關進行交互。
相對比而言:
- 第一種方案是最為典型的 MQTT-SN 部署方案,該方案非常適用於終端無公網通信需求且需要部署網關來統一管理的場景,例如典型的智能家居場景。
- 第二種方案常見於終端設備都部署在室外,它們通過移動網絡例如(NB-IoT) 直接與雲端直連,中間無法部署網關來處理設備請求。
- 第三種部署比較少見,它僅是方案 1、2 的一種折中。僅在服務端僅能提供 MQTT-SN 接入服務時會用到。
因此,MQTT-SN 主要應用於具有短距離、帶寬受限、低功耗等特點的應用場景,例如智慧城市、智能傢俱、水電氣表等。
使用 EMQX 接入 MQTT-SN 協議
EMQX 的 MQTT-SN 網關基於 MQTT-SN 1.2 版本實現。MQTT-SN 網關作為一個組件集成在 EMQX,可以允許將其部署在邊緣或雲端來實現上文提到的第一和第二種部署結構。
啓用 MQTT-SN 網關
在 EMQX 5.0 中,可以通過 Dashboard、HTTP-API 或配置文件來啓用 MQTT-SN 網關。
例如,開啓並配置監聽 UDP 1884 端口的 MQTT-SN 網關:
gateway.mqttsn {
mountpoint = "mqttsn/"
listeners.udp.default {
bind = 1884
max_connections = 10240000
max_conn_rate = 1000
}
}
客户端測試
使用 C 語言編寫的 MQTT-SN 客户端,來測試發佈訂閲,例如:
Client ID mqttsn1 連接並訂閲主題 t/a,
$ ./mqtt-sn-sub -i mqttsn1 -t t/a -p 1884 -d
使用 Client ID 為 mqttsn2 登錄到 MQTT-SN 網關,並對 t/a 主題發佈消息 Hi, This is mqttsn2 :
$ ./mqtt-sn-pub -i mqttsn2 -p 1884 -t t/a -m 'Hi, This is mqttsn2' -d
最終,能在 mqtt-sn-sub 端接收到該消息:
更多高級功能配置
配置客户端接入認證
由於 MQTT-SN v1.2 協議的連接報文只定義了 Client ID,沒有 Username 和 Password 。所以 MQTT-SN 網關目前僅支持 HTTP Server 認證
例如,通過配置文件,為 MQTT-SN 網關添加一個 HTTP 認證:
gateway.mqttsn {
authentication {
enable = true
backend = "http"
mechanism = "password_based"
method = "post"
connect_timeout = "5s"
enable_pipelining = 100
url = "<http://127.0.0.1:8080">
headers {
"content-type" = "application/json"
}
body {
clientid = "${clientid}"
}
pool_size = 8
request_timeout = "5s"
ssl.enable = false
}
}
在該認證方式中,將 Client ID 傳遞給 HTTP 服務,由 HTTP 服務來決定該客户端是否有接入系統的權限。
配置發佈訂閲權限
在 EMQX 5.0 中,所有主題的發佈訂閲權限都在授權(Authorization)中統一配置。例如,允許所有人發佈訂閲 mqttsn/ 開頭的主題:
獲取上下線事件
MQTT-SN 網關會將所有設備的上下線事件發佈到兩個專用的主題:
- 上線事件主題:
$SYS/brokers/<node>/gateway/mqtt-sn/clients/<clientid>/connected - 下線事件主題:
$SYS/brokers/<node>/gateway/mqtt-sn/clients/<clientid>/disconnected
例如,一條上線事件消息內容為:
{
"clientid": "abc",
"username": "undefined",
"ts": 1660285421750,
"sockport": 1884,
"protocol": "mqtt-sn",
"proto_ver": "1.2",
"proto_name": "MQTT-SN",
"keepalive": 10,
"ipaddress": "127.0.0.1",
"expiry_interval": 7200000,
"connected_at": 1660285421750,
"clean_start": false
}
當然,也可以通過規則引擎中的 $event/client_connected 和 $event/client_disconnected 事件來獲取 MQTT-SN 網關的上下線事件,具體可以參考:Event topic available for FROM clause
引用
[1] OASIS Open: MQTT-SN spec v1.2
[2] Urs Hunkeler & Hong Linh Truong: MQTT-S – A Publish/Subscribe Protocol For Wireless Sensor Networks
[3] EMQX 5.0 MQTT-SN Gateway introduction
[4] OASIS Open: MQTT-SN v2.0-wd17.docx
版權聲明: 本文為 EMQ 原創,轉載請註明出處。
原文鏈接:https://www.emqx.com/zh/blog/connecting-mqtt-sn-devices-using-emqx