使用 MQTT 通訊協定來與 IoT 中樞通訊
本文說明裝置如何使用受支援的 MQTT 行為來與 Azure IoT 中樞通訊。 IoT 中樞可使用下列項目讓裝置與 IoT 中樞裝置端點進行通訊:
- TCP 連接埠 8883 上的 MQTT v3.1.1 (英文)
- TCP 連接埠 443 上透過 WebSocket 的 MQTT v3.1.1。
注意
本文中提及的某些功能 (例如雲端對裝置傳訊、裝置對應項和裝置管理) 僅適用於 IoT 中樞的標準層。 如需基本和標準/免費 IoT 中樞層的詳細資訊,請參閱選擇適合您解決方案的 IoT 中樞層。
與 IoT 中樞通訊的所有裝置皆必須使用 TLS/SSL 加以保護。 因此,IoT 中樞不支援透過TCP 連接埠 1883 的不安全連線。
比較 IoT 中樞和事件方格中的 MQTT 支援
IoT 中樞不是功能完整的 MQTT 訊息代理程式,而且不支援 MQTT v3.1.1 標準中所指定的所有行為。 如果您的解決方案需要 MQTT,建議您使用 Azure 事件方格中的 MQTT 支援 (部分機器翻譯)。 事件方格會使用發佈/訂閱傳訊模型,在彈性階層式主題上啟用 MQTT 用戶端之間的雙向通訊。 其也可讓您將 MQTT 訊息路由傳送至 Azure 服務或自訂端點,以便進一步處理。
下表說明這兩個服務之間的 MQTT 支援差異:
IoT 中樞 | 事件方格 |
---|---|
裝置與雲端應用程式之間緊密結合的用戶端伺服器模型。 | 將發行者與訂閱者分離的發佈/訂閱模型。 |
有限支援 MQTT v3.1.1 的功能,有限支援預覽版 MQTT v5 的功能。 未規劃支援更多功能。 | 支援 MQTT v3.1.1 和 v5 通訊協定,並已規劃支援更多功能並提供產業合規性。 |
靜態的預先定義主題。 | 具有萬用字元支援的自訂階層式主題。 |
不支援雲端到裝置的廣播和裝置到裝置的通訊。 | 支援裝置到雲端、高展開傳送雲端到裝置的廣播,以及裝置到裝置的通訊模式。 |
訊息大小上限為 256 KB。 | 訊息大小上限為 512 KB。 |
連接到 IoT 中樞
裝置可以利用下列其中一個選項,使用 MQTT 通訊協定來連線到 IoT 中樞:
- Azure IoT SDK (部分機器翻譯)。
- 直接使用 MQTT 通訊協定。
許多公司和教育網路環境都會封鎖 MQTT 連接埠 (TCP 連接埠 8883)。 如果您無法在防火牆中開啟連接埠 8883,建議您使用 MQTT over WebSockets。 MQTT over WebSockets 會透過連接埠 443 進行通訊,在網路環境中幾乎一律會開啟此連接埠。 若要了解如何在使用 Azure IoT SDK 時,指定 MQTT 和 MQTT over WebSockets 通訊協定,請參閱使用裝置 SDK。
使用裝置 SDK
支援 MQTT 通訊協定的裝置 SDK 適用於 Java、Node.js、C、C# 和 Python。 裝置 SDK 使用選擇的驗證機制來建立對 IoT 中樞的連線。 若要使用 MQTT 通訊協定,用戶端通訊協定參數必須設定為 MQTT。 您也可以在用戶端通訊協定參數中指定 MQTT over WebSockets。 根據預設,裝置 SDK 會連接到 CleanSession 旗標設為 0 的 IoT 中樞,並使用 QoS 1 來與 IoT 中樞交換訊息。 雖然您可以設定 QoS 0 以加快訊息交換速度,但您應該注意,傳遞不被保證也不會獲得認可。 基於這個理由,QoS 0 通常稱為「射後不理」。
當裝置連線到 IoT 中樞時,裝置 SDK 會提供方法讓裝置使用 IoT 中樞交換訊息。
下表包含每種支援語言的程式碼範例連結,並指定要用來以 MQTT 或 MQTT over WebSockets 通訊協定連線到 IoT 中樞的參數。
語言 | MQTT 通訊協定參數 | MQTT over WebSockets 通訊協定參數 |
---|---|---|
Node.js | azure-iot-device-mqtt.Mqtt | azure-iot-device-mqtt.MqttWs |
Java | IotHubClientProtocol.MQTT | IotHubClientProtocol.MQTT_WS |
C | MQTT_Protocol | MQTT_WebSocket_Protocol |
C# | TransportType.Mqtt | 如果 MQTT 失敗,TransportType.Mqtt 會回復為 MQTT over WebSockets。 若只要指定 MQTT over WebSockets,請使用 TransportType.Mqtt_WebSocket_Only |
Python | 預設支援 MQTT | 在呼叫中新增 websockets=True 以建立用戶端 |
下列片段示範如何在使用 Azure IoT Node.js SDK 時,指定 MQTT over WebSockets 通訊協定:
var Client = require('azure-iot-device').Client;
var Protocol = require('azure-iot-device-mqtt').MqttWs;
var client = Client.fromConnectionString(deviceConnectionString, Protocol);
下列片段示範如何在使用 Azure IoT Python SDK 時,指定 MQTT over WebSockets 通訊協定:
from azure.iot.device.aio import IoTHubDeviceClient
device_client = IoTHubDeviceClient.create_from_connection_string(deviceConnectionString, websockets=True)
重要
本文包含使用共用存取簽章 (也稱為對稱金鑰驗證) 連線裝置的步驟。 此驗證方法方便進行測試和評估,但使用 X.509 憑證來驗證裝置是更安全的方法。 若要深入了解,請參閱安全性最佳做法>連線安全性。
預設 keep-alive 逾時
為了確保用戶端/IoT 中樞連線保持運作,服務與用戶端會定期互傳 keep-alive Ping。 使用 IoT SDK 的用戶端會以下表所定義的間隔傳送 keep-alive:
語言 | 預設 keep-alive 間隔 | 可設定 |
---|---|---|
Node.js | 180 秒 | No |
Java | 230 秒 | 是 |
C | 240 秒 | 是 |
C# | 300 秒* | 是 |
Python | 60 秒鐘 | 是 |
*C# SDK 會將 MQTT KeepAliveInSeconds 屬性的預設值定義為 300 秒。 事實上,SDK 會在所設定的每個 keep-alive 持續期間傳送四次 Ping 要求。 換句話說,SDK 每隔 75 秒就會傳送一次 keep-alive Ping。
遵循 MQTT v3.1.1 規格 (英文),IoT 中樞的 keep-alive Ping 間隔是用戶端 keep-alive 值的 1.5 倍;不過,IoT 中樞會將伺服器端的逾時上限限制為 29.45 分鐘 (1767 秒)。 有此限制是因為所有 Azure 服務都會繫結至 Azure 負載平衡器 TCP 閒置逾時,也就是 29.45 分鐘。
例如,使用 Java SDK 的裝置會傳送保持運作 Ping,然後失去網路連線能力。 230 秒之後,裝置會失去 keep-alive Ping,因為其離線。 不過,IoT 中樞不會立即關閉連線 - 其會等待另一個 (230 * 1.5) - 230 = 115
秒,再中斷裝置的連線,錯誤為 404104 DeviceConnectionClosedRemotely。
您可以設定的最大用戶端 keep-alive 值是 1767 / 1.5 = 1177
秒。 任何流量都會重設 keep-alive。 例如,成功重新整理共用存取簽章 (SAS) 權杖,即會重設 keep-alive。
將裝置應用程式從 AMQP 移轉至 MQTT
如果您使用裝置 SDK,則需要在用戶端初始化中變更通訊協定參數 (如上所述),才能從使用 AMQP 切換為 MQTT。
這麼做時,請務必檢查下列項目︰
AMQP 在許多情況下會傳回錯誤,而 MQTT 會終止連線。 因此,可能需要稍微變更您的例外狀況處理邏輯。
MQTT 在接收雲端到裝置訊息時不支援拒絕作業。 如果您的後端應用程式需要接收來自裝置應用程式的回應,請考慮使用直接方法。
Python SDK 不支援 AMQP。
直接使用 MQTT 通訊協定 (作為裝置)
如果裝置無法使用裝置 SDK,仍可使用連接埠 8883 上的 MQTT 通訊協定連線到公用裝置端點。
在 CONNECT 封包中,裝置應使用下列值:
在 [ClientId] 欄位中,使用 deviceId。
在 [Username] 欄位中,使用
{iotHub-hostname}/{device-id}/?api-version=2021-04-12
,其中{iotHub-hostname}
是 IoT 中樞的完整CName
。例如,如果您的 IoT 中樞名稱是 contoso.azure-devices.net ,而且如果您的裝置名稱是 MyDevice01,則完整的 [Username] 欄位應包含:
contoso.azure-devices.net/MyDevice01/?api-version=2021-04-12
建議您將 API 版本包含在欄位中。 否則,可能會導致非預期的行為。
在 [Password] 欄位中,使用 SAS 權杖。 SAS 權杖的格式與 HTTPS 和 AMQP 通訊協定的格式相同:
SharedAccessSignature sig={signature-string}&se={expiry}&sr={URL-encoded-resourceURI}
注意
如果您使用 X.509 憑證驗證,則不需要 SAS 權杖密碼。 如需詳細資訊,請參閱教學課程:建立和上傳用於測試的憑證 (部分機器翻譯),並遵循 TLS/SSL 設定一節中的程式碼指示。
如需如何產生 SAS 權杖的詳細資訊,請參閱使用共用存取簽章來控制對 IoT 中樞的存取權 (部分機器翻譯) 的使用 SAS 權杖作為裝置 (部分機器翻譯) 一節。
您也可以使用跨平台的適用於 Visual Studio Code 的 Azure IoT 中樞延伸模組 (英文) 或 CLI 延伸模組命令 az iot hub generate-sas-token,快速產生 SAS 權杖。 然後,您可以將 SAS 權杖複製並貼到您自己的程式碼中,以進行測試。
如需直接使用 MQTT 的教學課程,請參閱在不使用裝置 SDK 的情況下使用 MQTT 來開發 IoT 裝置用戶端 (部分機器翻譯)。
使用適用於 Visual Studio Code 的 Azure IoT 中樞延伸模組
在側邊列中,展開 [Azure IoT 中樞] 區段底下的 [裝置] 節點。
以滑鼠右鍵按一下您的 IoT 裝置,然後從捷徑功能表中選取 [產生裝置的 SAS 權杖]。
在輸入方塊中輸入 SAS 權杖的到期時間 (以小時為單位),然後選取 Enter 鍵。
SAS 權杖已建立並複製到剪貼簿。
產生的 SAS 權杖具有下列結構:
HostName={iotHub-hostname};DeviceId=javadevice;SharedAccessSignature=SharedAccessSignature sr={iotHub-hostname}%2Fdevices%2FMyDevice01%2Fapi-version%3D2016-11-14&sig=vSgHBMUG.....Ntg%3d&se=1456481802
使用 MQTT 連線時,此權杖中作為 [Password] 欄位的部分是︰
SharedAccessSignature sr={iotHub-hostname}%2Fdevices%2FMyDevice01%2Fapi-version%3D2016-11-14&sig=vSgHBMUG.....Ntg%3d&se=1456481802
裝置應用程式可以在 CONNECT 封包中指定 Will 訊息。 裝置應用程式應該使用 devices/{device-id}/messages/events/
或 devices/{device-id}/messages/events/{property-bag}
作為 Will 主題名稱,以定義要當作遙測訊息轉送的 Will 訊息。 在此情況下,如果網路連線已關閉,但先前並未接收到來自裝置的 DISCONNECT 封包,則 IoT 中樞會將 CONNECT 封包中提供的 Will 訊息傳送到遙測通道。 遙測通道可以是預設的事件端點,或是 IoT 中樞路由所定義的自訂端點。 訊息具有 iothub-MessageType 屬性,且已為它指派 Will 值。
直接使用 MQTT 通訊協定 (作為模組)
您可以使用模組 ID,透過 MQTT 連線到 IoT 中樞,方法和作為裝置連線到 IoT 中樞類似。 如需作為裝置透過 MQTT 連線到 IoT 中樞的詳細資訊,請參閱直接使用 MQTT 通訊協定 (作為裝置)。 不過,您必須使用下列值:
將用戶端識別碼設定為
{device-id}/{module-id}
。如果以使用者名稱和密碼來進行驗證,請將使用者名稱設定為
<hubname>.azure-devices.net/{device_id}/{module_id}/?api-version=2021-04-12
,並使用與模組身分識別相關聯的 SAS 權杖來作為密碼。使用
devices/{device-id}/modules/{module-id}/messages/events/
作為主題來發佈遙測。使用
devices/{device-id}/modules/{module-id}/messages/events/
作為 WILL 主題。使用
devices/{device-id}/modules/{module-id}/#
作為主題來接收訊息。GET 和 PATCH 這對主題在模組和裝置中都一樣。
這對狀態主題在模組和裝置中都一樣。
如需有關搭配模組使用 MQTT 的詳細資訊,請參閱使用 IoT Edge 來發佈和訂閱,並深入了解 IoT Edge 中樞 MQTT 端點。
在沒有 Azure IoT SDK 的情況下使用 MQTT 的範例
IoT MQTT 範例存放庫 (英文) 包含 C/C++、Python 和 CLI 範例,會示範如何在不使用 Azure 裝置 SDK 的情況下,傳送遙測訊息、接收雲端到裝置的訊息,以及使用裝置對應項。
C/C++ 範例會使用 Eclipse Mosquitto (英文) 程式庫、Python 範例會使用 Eclipse Paho (英文),CLI 範例則會使用 mosquitto_pub
。
若要深入了解,請參閱教學課程 - 使用 MQTT 來開發 IoT 裝置用戶端。
TLS/SSL 組態
若要直接使用 MQTT 通訊協定,您的用戶端「必須」透過 TLS/SSL 進行連線。 嘗試略過此步驟會因連線錯誤而發生失敗。
若要建立 TLS 連線,您可能必須下載並參考 Azure 所使用的 DigiCert 根憑證。 在 2023 年 2 月 15 日至 10 月 15 日之間,Azure IoT 中樞會將其 TLS 根憑證從 DigiCert Baltimore 根憑證移轉至 DigiCert Global Root G2。 在移轉期間,請在裝置上同時備有這兩種憑證,以確保連線能力。 如需移轉的詳細資訊,請參閱將 IoT 資源移轉至新的 TLS 憑證根 (部分機器翻譯)。如需這些憑證的詳細資訊,請參閱 Digicert 的網站 (英文)。
下列範例示範如何使用 Eclipse Foundation 的 Paho MQTT 程式庫 (英文) Python 版本來實作此設定。
首先,從您的命令列環境安裝 Paho 程式庫:
pip install paho-mqtt
接著,以 Python 指令碼實作用戶端。 取代下列程式碼片段中的這些預留位置:
<local path to digicert.cer>
是包含 DigiCert 根憑證的本機檔案路徑。 您可以在「適用 C 的 Azure IoT SDK」中,從 certs.c 複製憑證資訊來建立此檔案。包含-----BEGIN CERTIFICATE-----
和-----END CERTIFICATE-----
這兩行、移除每一行開頭和結尾的"
標記,以及移除每一行結尾的\r\n
字元。<device id from device registry>
是您新增至 IoT 中樞的裝置識別碼。<generated SAS token>
是所建立裝置的 SAS 權杖,如本文前面所述。<iot hub name>
是 IoT 中樞的名稱。
from paho.mqtt import client as mqtt
import ssl
path_to_root_cert = "<local path to digicert.cer file>"
device_id = "<device id from device registry>"
sas_token = "<generated SAS token>"
iot_hub_name = "<iot hub name>"
def on_connect(client, userdata, flags, rc):
print("Device connected with result code: " + str(rc))
def on_disconnect(client, userdata, rc):
print("Device disconnected with result code: " + str(rc))
def on_publish(client, userdata, mid):
print("Device sent message")
client = mqtt.Client(client_id=device_id, protocol=mqtt.MQTTv311)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish
client.username_pw_set(username=iot_hub_name+".azure-devices.net/" +
device_id + "/?api-version=2021-04-12", password=sas_token)
client.tls_set(ca_certs=path_to_root_cert, certfile=None, keyfile=None,
cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
client.tls_insecure_set(False)
client.connect(iot_hub_name+".azure-devices.net", port=8883)
client.publish("devices/" + device_id + "/messages/events/", '{"id":123}', qos=1)
client.loop_forever()
若要使用裝置憑證進行驗證,請使用下列程式碼片段中指定的變更來更新先前的程式碼片段。 如需如何準備憑證式驗證的詳細資訊,請參閱使用 X.509 CA 憑證驗證裝置的取得 X.509 CA 憑證一節。
# Create the client as before
# ...
# Set the username but not the password on your client
client.username_pw_set(username=iot_hub_name+".azure-devices.net/" +
device_id + "/?api-version=2021-04-12", password=None)
# Set the certificate and key paths on your client
cert_file = "<local path to your certificate file>"
key_file = "<local path to your device key file>"
client.tls_set(ca_certs=path_to_root_cert, certfile=cert_file, keyfile=key_file,
cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
# Connect as before
client.connect(iot_hub_name+".azure-devices.net", port=8883)
傳送裝置到雲端訊息
裝置連線之後,可以使用 devices/{device-id}/messages/events/
或 devices/{device-id}/messages/events/{property-bag}
作為主題名稱,將訊息傳送至 IoT 中樞。 {property-bag}
元素可讓裝置以 URL 編碼格式傳送具有其他屬性的訊息。 例如:
RFC 2396-encoded(<PropertyName1>)=RFC 2396-encoded(<PropertyValue1>)&RFC 2396-encoded(<PropertyName2>)=RFC 2396-encoded(<PropertyValue2>)…
注意
這個 {property_bag}
元素與 HTTPS 通訊協定中的查詢字串使用相同的編碼。
注意
如果您要將 D2C 訊息路由傳送至 Azure 儲存體帳戶,而且想要利用 JSON 編碼,則必須指定「內容類型」和「內容編碼」資訊,包括 $.ct=application%2Fjson&$.ce=utf-8
(屬於上一個注意事項所述的 {property_bag}
一部分)。
這些屬性的格式是通訊協定特有的。 IoT 中樞會將這些屬性 (Attribute) 轉譯成其對應的系統屬性 (Property)。 如需詳細資訊,請參閱 IoT 中樞訊息路由查詢語法的系統屬性一節。
下列清單會描述 IoT 中樞實作特有的行為:
「IoT 中樞」不支援 QoS 2 訊息。 如果裝置應用程式發佈 QoS 2 的訊息,IoT 中樞會關閉網路連接。
「IoT 中樞」不會保存「保留」訊息。 如果裝置傳送 RETAIN 旗標設定為 1 的訊息,「IoT 中樞」會在訊息中新增 mqtt-retain 應用程式屬性。 在此情況下,「IoT 中樞」不會保存保留訊息,而是會傳遞給後端應用程式。
IoT 中樞僅支援每個裝置有一個作用中 MQTT 連接。 任何代表相同裝置識別碼的新 MQTT 連線都會導致 IoT 中樞卸除現有的連線,並將 400027 ConnectionForcefullyClosedOnNewConnection 記錄到 IoT 中樞記錄
若要根據訊息本文來路由傳送訊息,您必須先將屬性 'contentType' (
ct
) 新增至 MQTT 主題結尾,並將其值設定為application/json;charset=utf-8
,如下列範例所示。 如需如何根據訊息屬性或訊息本文來路由傳送訊息的詳細資訊,請參閱 IoT 中樞訊息路由查詢語法文件。devices/{device-id}/messages/events/$.ct=application%2Fjson%3Bcharset%3Dutf-8
如需詳細資訊,請參閱使用 IoT 中樞傳送裝置到雲端與雲端到裝置的訊息。
接收雲端到裝置訊息
若要從 IoT 中樞接收訊息,裝置應該使用 devices/{device-id}/messages/devicebound/#
做為主題篩選來進行訂閱。 「主題篩選」中的多層級萬用字元 #
僅用來允許裝置接收主題名稱中的更多屬性。 IoT 中樞不允許使用 #
或 ?
萬用字元來篩選子主題。 由於「IoT 中樞」不是一般用途的發行/訂閱傳訊訊息代理程式,因此只支援已記載的主題名稱和主題篩選。 裝置一次只能訂閱五個主題。
裝置在成功訂閱 IoT 中樞的裝置特定端點 (由 devices/{device-id}/messages/devicebound/#
主題篩選條件代表) 之後,才會收到來自 IoT 中樞的訊息。 建立訂閱之後,裝置將會接收在訂閱之後傳送給它的雲端到裝置訊息。 如果裝置是在 CleanSession 旗標設定為 0 的情況下連線,訂閱將會跨不同的工作階段持續保留。 在此情況下,下次裝置以 CleanSession 0 進行連線時,就會收到中斷連線時傳送給它的任何未送訊息。 如果裝置使用設定為 1 的 CleanSession 旗標,則必須等到其訂閱 IoT 中樞的裝置端點之後,才會收到任何來自該 IoT 中樞的訊息。
IoT 中樞 使用 傳遞訊息主題名稱 devices/{device-id}/messages/devicebound/
,或devices/{device-id}/messages/devicebound/{property-bag}
有訊息屬性時。 {property-bag}
包含訊息屬性的 url 編碼索引鍵/值組。 屬性包中只會包含應用程式屬性和使用者可設定的系統屬性 (例如 messageId 或 correlationId)。 系統屬性名稱具有前置詞 $,但應用程式屬性會使用沒有前置詞的原始屬性名稱。 如需屬性包格式的詳細資訊,請參閱傳送裝置到雲端的訊息。
在雲端到裝置訊息中,屬性包中的值會如下表中表示:
屬性值 | 表示法 | 描述 |
---|---|---|
null |
key |
只有索引鍵會出現在屬性包中 |
空字串 | key= |
索引鍵後面接著沒有值的等號 |
非 Null、非空白值 | key=value |
索引鍵後面接著等號和值 |
下列範例顯示包含三個應用程式屬性的屬性包:prop1,值為 null
;prop2,空字串 ("");和 prop3,值為「a string」。
/?prop1&prop2=&prop3=a%20string
當裝置應用程式訂閱具有 QoS 2 的主題時,IoT 中樞會在 SUBACK 封包中授與最大 QoS 層級 1。 之後,IoT 中樞會使用 QoS 1 將訊息傳遞給裝置。
擷取裝置對應項屬性
首先,裝置會訂閱 $iothub/twin/res/#
,以接收作業的回應。 然後,它會傳送空白訊息給主題 $iothub/twin/GET/?$rid={request id}
,其中已填入要求 ID 的值。 服務接著會使用和要求相同的要求 ID,傳送內含關於 $iothub/twin/res/{status}/?$rid={request-id}
主題之裝置對應項資料的回應訊息。
要求識別碼可以是任何有效的訊息屬性值,並將狀態驗證為整數。 如需詳細資訊,請參閱使用 IoT 中樞傳送裝置到雲端與雲端到裝置的訊息。
回應本文包含裝置對應項的 properties 區段,如以下回應範例所示:
{
"desired": {
"telemetrySendFrequency": "5m",
"$version": 12
},
"reported": {
"telemetrySendFrequency": "5m",
"batteryLevel": 55,
"$version": 123
}
}
可能的狀態碼如下︰
狀態 | 描述 |
---|---|
200 | 成功 |
429 | 太多要求 (已節流)。 如需詳細資訊,請參閱 IoT 中樞節流 |
5** | 伺服器錯誤 |
如需詳細資訊,請參閱了解和使用 Azure IoT 中樞的裝置對應項。
更新裝置對應項的報告屬性
為了更新所報告的屬性,裝置會透過對指定 MQTT 主題進行發佈,將要求發給 IoT 中樞。 IoT 中樞處理該要求之後,會透過發行至另一個主題,回應更新作業的成功或失敗狀態。 裝置可以訂閱此主題,以收到其對應項更新要求結果的通知。 為了在 MQTT 中實作此類型的要求/回應互動,我們會使用裝置一開始在其更新要求中所提供的要求識別碼標記法 ($rid
)。 此要求識別碼也會包含在來自 IoT 中樞的回應,以允許裝置讓回應與其先前的特定要求相互關聯。
下列順序說明在 IoT 中樞的裝置對應項中,裝置如何更新報告的屬性︰
裝置必須訂閱
$iothub/twin/res/#
主題,才能從 IoT 中樞接收作業的回應。裝置會將包含裝置對應項新的訊息傳送至
$iothub/twin/PATCH/properties/reported/?$rid={request-id}
主題。 此訊息包含要求 ID 值。服務接著會傳送回應訊息,其中包含
$iothub/twin/res/{status}/?$rid={request-id}
主題上報告之屬性集合的新 ETag 值。 這個回應訊息使用和要求相同的要求 ID。
要求訊息本文會包含 JSON 文件,其包含已報告屬性的新值。 JSON 文件中的每個成員會在裝置對應項的文件中更新或新增對應的成員。 設定為 null
的成員會從包含的物件中刪除成員。 例如:
{
"telemetrySendFrequency": "35m",
"batteryLevel": 60
}
可能的狀態碼如下︰
狀態 | 描述 |
---|---|
204 | 成功 (不會傳回任何內容) |
400 | 不正確的要求。 JSON 格式錯誤 |
429 | 要求過多 (已節流),根據 IoT 中樞節流 |
5** | 伺服器錯誤 |
下列 Python 程式碼片段示範使用 Paho MQTT 用戶端,透過 MQTT 進行的對應項報告屬性更新流程:
from paho.mqtt import client as mqtt
# authenticate the client with IoT Hub (not shown here)
client.subscribe("$iothub/twin/res/#")
rid = "1"
twin_reported_property_patch = "{\"firmware_version\": \"v1.1\"}"
client.publish("$iothub/twin/PATCH/properties/reported/?$rid=" +
rid, twin_reported_property_patch, qos=0)
當上述程式碼片段中的對應項報告屬性更新流程成功時,來自 IoT 中樞的發佈訊息會有下列主題:$iothub/twin/res/204/?$rid=1&$version=6
,其中 204
是表示成功的狀態碼、$rid=1
會對應至裝置在程式碼中提供的要求識別碼,$version
則會對應至更新之後裝置對應項報告屬性區段的版本。
如需詳細資訊,請參閱了解和使用 Azure IoT 中樞的裝置對應項。
接收所需屬性更新通知
當連接裝置時,IoT 中樞傳送通知給主題 $iothub/twin/PATCH/properties/desired/?$version={new-version}
,其中包含解決方案後端所執行的更新內容。 例如:
{
"telemetrySendFrequency": "5m",
"route": null,
"$version": 8
}
和屬性更新一樣,null
值表示將要刪除的 JSON 物件成員。 另外,$version
指出對應項所需屬性區段的新版本。
重要
IoT 中樞只會在連接裝置時產生變更通知。 請務必實作裝置重新連線流程,以便讓 IoT 中樞與裝置應用程式兩者所需的屬性保持同步。
如需詳細資訊,請參閱了解和使用 Azure IoT 中樞的裝置對應項。
回應直接方法
首先,裝置必須訂閱 $iothub/methods/POST/#
。 IoT 中樞會將方法要求傳送至主題 $iothub/methods/POST/{method-name}/?$rid={request-id}
,其中含有有效的 JSON 或空白本文。
若要回應,裝置會將具有有效 JSON 的或內文空白的訊息傳送至 $iothub/methods/res/{status}/?$rid={request-id}
主題。 在此訊息中,要求識別碼必須與要求訊息中的相符,且狀態必須是整數。
如需詳細資訊,請參閱了解和叫用來自 IoT 中樞的直接方法。
下一步
若要深入了解如何使用 MQTT,請參閱:
- MQTT 文件 (英文)
- 在不使用裝置 SDK 的情況下使用 MQTT 來開發 IoT 裝置用戶端 (部分機器翻譯)
- MQTT 應用程式範例 (英文)
若要深入了解如何使用 IoT 裝置 SDK,請參閱:
若要深入了解如何規劃 IoT 中樞部署,請參閱: