1.MQTT簡介
MQTT協議是一個面向物聯網應用的即時通訊協議,使用TCP/IP提供網路連線,能夠對負載內容實現訊息遮蔽傳輸,開銷小,可以有效降低網路流量。
參考博主線上博文:玩轉PubSubClient MQTT庫
特點及功能
- 長連線協議(保持心跳,keepAlive)
- 終端資料點上報,支援的資料點型別包括
整型(int)
浮點數(float)
字串(string)
JSON格式
二進位制資料
- 平臺訊息下發
- 基於Topic的訂閱、釋出以及訊息推送,可以實現裝置間的訊息單播以及組播
典型應用場景
MQTT協議適用於裝置和平臺需要保持長連線的使用場景,MQTT特點在於可以實現裝置間的訊息單播以及組播,可以不依賴於其他服務(下發命令服務,推送服務等)實現讓裝置以應用伺服器的方式對真實裝置進行管理和控制。
讀者所需知識儲備:
- 玩轉PubSubClient MQTT庫
- 玩轉OneNET物聯網平臺之簡介
2.MQTT接入說明
接入流程分為:
- 平臺域(也就是OneNet平臺上的操作)
- 裝置域(8266裝置上的SDK,我們這裡用PubSubClient)
接入步驟如下:
2.1 Step1 —— 建立產品,選擇接入協議
- 首先您需要在平臺建立一個接入協議為MQTT的產品,檢視產品建立
- 建立產品後,記錄該產品的產品ID(ProductId)
2.2 Step2 —— 建立裝置,記錄裝置ID等資訊
建立裝置有兩種方式:
- 第一種 可以通過頁面點選新增裝置,輸入裝置名稱和鑑權資訊(即裝置編號,在8266中我們可以使用 ESP+Mac地址的方式或者ESP+ChipId的方式),具體平臺的資源模型可詳情請檢視第一章 資源模型,並記錄下該裝置編號(deviceId).
- 第二種 可以通過呼叫建立裝置API 實現裝置的建立,輸入裝置的裝置名、接入協議、鑑權資訊以及MasterKey等資訊,即可在平臺上建立裝置(博主比較喜歡這一種,也比較靈活)。
2.3 Step3 —— 建立裝置與平臺間的協議連線
- MQTT伺服器地址域名為:mqtt.heclouds.com
使用Step1和Step2中的引數作為登入引數,使用SDK中的對應介面組織MQTT連線報文,傳送到平臺,與平臺建立MQTT連線
若已經連線成功,在裝置資訊中會看到一個線上標記:
對於初學者,博主建議先用OneNet提供的MQTT除錯工具來試玩一下,已親測可用。
2.4 Step4 —— 資料流建立,資料點上傳
- 利用SDK中提供的介面函式,編寫程式碼將資料上傳到平臺
2.5 Step5 —— 資料流展示,檢視資料點
- 在OneNET上的裝置管理下點選資料展示,進入資料展示頁面,點選下拉選單,檢視近期上傳的資料點;也可以選擇時間區間來檢視歷史時間
3. MQTT API
API根據用途做了幾種分類,博主這裡不重複,請參考 玩轉OneNET物聯網平臺之簡介
當然,OneNet為了簡單方便除錯API,也給我們提供了除錯介面,具體請參考
博主在這裡不會去講解各個API的詳細用法,請大家自行去查閱官方文件(查閱官方文件也是鍛鍊能力的一種)。
3.1 新增裝置
- 具體參考 OneNet官方文件 - 新增裝置
- 此方法比較重要,請仔細理解
3.2 註冊裝置
- 具體參考 OneNet官方文件 - 註冊裝置
3.3 更新裝置資訊
- 具體參考 OneNet官方文件 - 更新裝置資訊
3.4 查詢裝置詳情
- 具體參考 OneNet官方文件 - 查詢裝置詳情
3.5 批量查詢裝置資訊
- 具體參考 OneNet官方文件 - 批量查詢裝置資訊
3.6 批量查詢裝置狀態
- 具體參考 OneNet官方文件 - 批量查詢裝置狀態
3.7 刪除裝置
- 具體參考 OneNet官方文件 - 刪除裝置
3.8 新增資料流
- 具體參考 OneNet官方文件 - 新增資料流
3.9 更新資料流屬性
- 具體參考 OneNet官方文件 - 更新資料流屬性
3.10 查詢資料流詳情
- 具體參考 OneNet官方文件 - 查詢資料流詳情
3.11 批量查詢資料流資訊
- 具體參考 OneNet官方文件 - 批量查詢資料流資訊
3.12 刪除資料流
- 具體參考 OneNet官方文件 - 刪除資料流
3.13 查詢裝置歷史資料
- 具體參考 OneNet官方文件 - 查詢裝置歷史資料
3.14 批量查詢裝置最新資料
- 具體參考 OneNet官方文件 - 批量查詢裝置最新資料
3.15 新增資料點
- 具體參考 OneNet官方文件 - 新增資料點
3.16 上傳檔案
- 具體參考 OneNet官方文件 - 上傳檔案
3.17 獲取檔案
- 具體參考 OneNet官方文件 - 獲取檔案
3.18 傳送命令
- 具體參考 OneNet官方文件 - 傳送命令
3.19 查詢命令狀態
- 具體參考 OneNet官方文件 - 查詢命令狀態
3.20 查詢命令響應
- 具體參考 OneNet官方文件 - 查詢命令響應
3.21 查詢裝置歷史命令
- 具體參考 OneNet官方文件 - 查詢裝置歷史命令
3.22 新增觸發器
- 具體參考 OneNet官方文件 - 新增觸發器
3.23 更新觸發器
- 具體參考 OneNet官方文件 - 更新觸發器
3.24 查詢觸發器
- 具體參考 OneNet官方文件 - 查詢觸發器
3.25 刪除觸發器
- 具體參考 OneNet官方文件 - 刪除觸發器
3.26 新增apikey
- 具體參考 OneNet官方文件 - 新增apikey
3.27 更新apikey
- 具體參考 OneNet官方文件 - 更新apikey
3.28 查詢apikey
- 具體參考 OneNet官方文件 - 查詢apikey
3.29 刪除apikey
- 具體參考 OneNet官方文件 - 刪除apikey
3.30 釋出訊息
- 具體參考 OneNet官方文件 - 釋出訊息
3.31 查詢訂閱topic的裝置
- 具體參考 OneNet官方文件 - 查詢訂閱topic的裝置
3.32 查詢裝置訂閱的topic
- 具體參考 OneNet官方文件 - 查詢裝置訂閱的topic
3.33 查詢產品的topic
- 具體參考 OneNet官方文件 - 查詢產品的topic
4.裝置端接入MQTT流程
前提:
- 讀者已經瞭解MQTT協議
- 讀者已經在OneNet上建立了Mqtt協議產品,比如博主這裡建立了彩燈-MQTT專案
4.1 連線鑑權
在 2.3 Step3 —— 建立裝置與平臺間的協議連線中說到,我們第一步就是和OneNet平臺建立連線鑑權:
- 裝置向平臺發起 connect 請求.connect 中攜帶鑑權資訊
- 平臺拿到鑑權資訊進行鑑權
- 鑑權通過後,如果 cleansession=0, 平臺將會載入儲存的裝置的一些資訊.如訂閱列表; 如果 cleansession=1, 裝置沒有儲存資訊在平臺,則不載入裝置相關資訊
- 返回鑑權結果 ConnAck 報文
4.2 訊息釋出
4.2.1 資料點上報協議說明
裝置使用publish報文來上傳資料點, 報文格式如下:
- VariableHeader
欄位 | Field名稱 | 說明 | 格式 |
---|---|---|---|
Field1 | TopicName=”$dp” | $dp為系統上傳資料點的指令 | 2位元組字串長度 + utf8字串 |
- Payload
Payload包含真正的資料點內容,支援的格式如下:
資料型別 1(type == 1)格式說明:
資料型別 2(type == 2)格式說明:
資料型別 3(type == 3)格式說明:
資料型別 4(type ==4)格式說明:
資料型別 5(type ==5)格式說明:
資料型別 6(type ==6)格式說明:
資料型別 7(type == 7)格式說明:(每次最多 500 個資料流的浮點數):
4.2.2 資料點上報 —— 質量等級Qos0(Client->Server)
- 裝置釋出 Qos0 訊息(上報資料點)
- 平臺收到上報資料點後儲存起來.
4.2.3 資料點上報 —— 質量等級Qos1(Client->Server)
- 裝置釋出 Qos1 訊息(上報資料點)
- 平臺收到上報資料點後儲存起來.
- 平臺給裝置回覆相應的 PubAck報文
4.2.4 資料點上報 —— 質量等級Qos2(Client->Server)
- 裝置釋出 Qos2 訊息(上報資料點)
- 平臺收到上報資料點後儲存起來
- 平臺給裝置回覆相應的 PubRec 報文
- 裝置需回覆平臺 PubRel 報文,如超時不回平臺則會斷開相應連線
- 平臺給裝置回覆 PubComp 報文
注意:
- 資料點上報功能不支援 Retain 特性
4.2.5 下發平臺命令協議說明
平臺使用publish 報文來下發平臺指令, 報文格式如下:
FixHeader:
- 參考MQTT篇關於固定頭的說明
VariableHeader:
欄位 | Field名稱 | 說明 | 格式 |
---|---|---|---|
Field1 | TopicName=”$creq/cmduuid” | $creq 為系統下發Cmd 的指令,cmduuid 為該條指令的uuid | 2 位元組字串長度+ utf8 字串 |
Payload:
- Payload 包含真正的指令內容
注意點:
- 因為這裡的cmduuid為某條指令的uuid,所以我們可以考慮正規表示式的topic
4.2.6 下發平臺命令 —— 質量等級Qos0(Server->Client)
- 平臺向裝置傳送topic 為$creq 的訊息(該topic 為平臺命令).
裝置收到topic 為$creq 的topic 時,需將其作為平臺下發的指令來處理.
注意:
- 目前命令下發以Qos0 級別進行推送
4.2.7 命令回覆協議說明
平臺使用publish 報文來回復平臺指令, 報文格式如下:
FixHeader:
- 參考MQTT篇關於固定頭的說明
VariableHeader:
欄位 | Field名稱 | 說明 | 格式
---|---|---|---
Field1 | TopicName=”$crsp/cmduuid” | $crsp為系統處理裝置回覆cmd 的指令,cmduuid 為該條指令的uuid | 2 位元組字串長度+ utf8 字串
Payload:
- Payload 包含真正的指令內容
注意點:
- 因為這裡的cmduuid為某條指令的uuid,所以我們可以考慮正規表示式的topic
4.2.8 命令回覆 —— 質量等級Qos0(Client->Server)
4.2.9 命令回覆 —— 質量等級Qos1(Client<-> Server)
- 如果裝置回覆響應時以Qos1 回覆,則平臺需要給裝置回覆一個Puback 報文
4.2.10 命令回覆 —— 質量等級Qos2(Client<-> Server)
如果裝置回覆響應時以Qos2 回覆,則:
- 1.平臺需回覆裝置一個PubRec 報文
- 2.裝置在收到PubRec 後需向平臺回覆PubRel 報文
- 3.平臺收到PubRel 報文後,向裝置回覆PubComp 報文
4.3 建立Topic
- 裝置通過傳送HTTP 請求進行topic 的建立操作.
- 平臺收到請求後建立topic 並返回結果.
請求及響應定義如下:
4.4 訂閱
- 裝置發起訂閱請求報文
- 平臺收到請求後更新topic 列表
- 平臺給裝置回覆SubAck報文
注意:
- subscribe 的request qos 級別可以為0、1、2
4.5 取消訂閱
- 裝置發起取消訂閱請求
- 平臺收到請求後更新topic 列表
- 平臺給裝置回覆UnSubAck
4.6 推送裝置Topic
4.6.1 Publish 報文推送協議說明
FixHeader:
- 參考MQTT篇關於固定頭的說明
VariableHeader:
欄位 | Field名稱 | 說明 | 格式
---|---|---|---
Field1 | TopicName | 填寫裝置訂閱的topic | 2 位元組字串長度+ utf8 字串
Payload:
- Payload 為裝置自定義內容
4.6.2 Publish 報文推送 —— 質量等級Qos0
- 裝置發起推送topic 請求(以Qos0 級別)
- 平臺收到請求後,將topic 以Qos0 級別推送到相關訂閱裝置(支援離線裝置推送)
- 平臺不返回PubAck 或PubRec 等報文
4.6.3 Publish 報文推送 —— 質量等級Qos1
- 裝置發起推送topic 請求(以Qos1 級別)
- 平臺收到請求後,將topic 以Qos1 級別推送到相關訂閱裝置(支援離線裝置推送)
- 平臺返回PubAck 報文
4.6.4 Publish 報文推送 —— 質量等級Qos2
- 裝置發起推送topic 請求(以Qos2 級別)
- 平臺收到請求後,回覆PubRec 報文
- 裝置收到PubRec 後需回覆PubRel 報文(如超時不回覆,平臺會斷開與裝置的連線)
- 平臺收到PubRel 報文後,回覆PubComp 給裝置
- 平臺在回覆PubComp 後會以Qos2 級別推送到相關訂閱裝置(支援離線裝置推送)
- 裝置需回覆PubRec 報文(如超時不回覆,平臺會斷開與裝置的連線)
- 平臺傳送PubRel 報文給裝置
- 裝置需回覆PubComp(釋出完成)
4.6.5 HTTP 請求推送
- 裝置以HTTP 的方式發起推送topic 請求
- 平臺收到請求後,將topic 推送到相關訂閱裝置.(目前只支援線上推送)
- 平臺返回推送結果
請求及響應定義如下:
4.7 離線Topic
普通推送(上面的推送裝置Topic)只針對線上裝置進行topic訊息的推送,離線裝置不會收到訂閱的topic 的訊息。
離線Topic則會將該訊息推送給線上以及離線裝置。
注意點:
- 如果裝置在上線時設定了clean session flag,服務端會刪除其訂閱的topic 及相關的離線topic 訊息。
- 如果裝置沒有設定clean session flag,如果有與該裝置相關的離線topic 訊息,則在鑑權成功後將離線訊息
推送給裝置。 - 遺囑訊息(will msg)只會推送給訂閱了該will topic 的線上的裝置,離線裝置不會收到。
- 離線訊息的有效期預設為2 天(暫不支援使用者設定有效期),伺服器只會推送在2 天內的最近10 條訊息。
4.8 資料點訂閱
含義:
- 同一產品下的裝置可以訂閱其他裝置的資料點,訂閱的topic 格式為:/deviceid/資料流名稱。即
被關注的裝置在上傳了該資料流名稱的資料點後,訂閱了該topic 的其他裝置都會收到上傳的資料點。
例子:
- A、B 裝置的deviceid 分別為9277、9278。
- A 裝置訂閱了名為/9278/9527 的topic(9278 為裝置B 的id,9527 為B 裝置上傳的資料流名稱)。
- B 裝置上傳了名為9527 的資料流(資料點為11; 15;78…)。
- A 裝置會收到多條(取決於裝置B 上傳的資料點的個數)推送的topic 名為/9278/9527 的publish 訊息,訊息的
payload 中則包含裝置B 上傳的資料點。
注意點:
- 目前支援訂閱的資料點的型別為Type1~Type7
5.常見問題
5.1 MQTT連線鑑權時,Payload中ClientIdentifier;UserName;UserPassword分別填寫什麼?
- ClientIdentifier: 建立裝置時得到的裝置ID,為數字字串;
- UserName: 註冊產品時,平臺分配的產品ID,為數字字串;
- UserPassword: 為裝置的鑑權資訊(即唯一裝置編號,SN),或者為apiKey,為字串。
5.2 MQTT需要在連線鑑權通過後才能傳送其它報文嗎?
- 是的,MQTT協議必須在鑑權通過後(收到ConnAck後),才能傳送後續報文進行互動,不然伺服器會直接丟棄報文。
5.3 MQTT可以訂閱Topic有什麼限制?
- OneNET不支援訂閱$開頭的系統Topic。
5.4 如何利用MQTT協議上傳資料到雲平臺?
- 裝置完成連線鑑權之後,將資料按照一定的格式(見協議文件說明)打包,將資料釋出到$dp系統Topic上即可。
5.5 訂閱之前是否需要建立Topic?
- 裝置在執行訂閱時,OneNET會自動判斷該Topic是否存在,若不存在則自動建立該Topic。
5.6 裝置可否通過訂閱的方式,獲取其他裝置的資料流資訊?
- 可以,可以通過訂閱 /device_id/資料流名 的方式,及時獲取到某裝置最新的資料點資訊。
5.7 裝置釋出訊息(Publish)有什麼限制??
- 釋出訊息只能在同一產品ID下進行,不能進行跨產品間的Publish訊息推送。
6. 新手手把手感受OneNet MQTT案例
博主這裡認為大家已經註冊了OneNet賬號。接下來請按照下面步驟進行:
6.1 建立 ESP8266智慧燈系統 產品(MQTT協議)
注意點:
- 務必選擇MQTT協議
建立完畢後,我們點選檢視具體的產品資訊:
注意點:
- 需要記錄產品ID,其用來區分產品唯一識別符號
- Master-APIkey,網路請求鑑權資訊,介面呼叫需要帶入
6.2 API除錯建立 deviceA和deviceB兩個裝置
API介面定義:
- 參考官方文件 建立裝置
操作步驟:
- 通過API除錯工具建立deviceA
http body:
{
"title": "mqtt_device_A",
"desc": "mqtt_device_A",
"tags": ["china", "mobile"],
"location": {
"lon": 109,
"lat": 23.54
},
"auth_info": "mqtt_device_A",
"other": {
"version": "1.0.0",
"manufacturer": "china mobile"
}
}
- 通過API除錯工具建立deviceB
http body:
{
"title": "mqtt_device_B",
"desc": "mqtt_device_B",
"tags": ["china", "mobile"],
"location": {
"lon": 109,
"lat": 23.54
},
"auth_info": "mqtt_device_B",
"other": {
"version": "1.0.0",
"manufacturer": "china mobile"
}
}
- 檢視裝置列表
6.3 官方工具除錯deviceA和deviceB
讀者請自行下載 MQTT-device 工具。下載完工具之後請複製出兩份,一個工具代表deviceA,一個工具代表deviceB,我們模擬Mqtt操作。
6.3.1 配置deviceA
注意點:
- 重點關注博主標紅的地方,DeviceID和ProductID、AuthInfo需要填寫讀者自身建立的
- 配置完畢連線伺服器
6.3.2 配置deviceB
注意點:
- 重點關注博主標紅的地方,DeviceID和ProductID、AuthInfo需要填寫讀者自身建立的
- 配置完畢連線伺服器
6.3.3 deviceA訂閱主題“deviceB_to_A”
注意點:
- 主題名為“deviceB_to_A”
6.3.4 deviceB訂閱主題“deviceA_to_B”
注意點:
- 主題名為“deviceA_to_B”
6.3.5 deviceB釋出資訊給deviceA
6.3.6 deviceA釋出資訊給deviceB
6.3.7 平臺下發命令給deviceA
6.3.8 deviceA上傳資料點到平臺
7.總結
本篇作為OneNet Mqtt篇的開頭篇,主要講解了Mqtt的使用注意事項,並且在除錯工具下模擬Mqtt的常用操作,請關注接下來的篇章。