分享方式:


瞭解IoT中樞的雲端到裝置傳訊

雲端到裝置訊息是從解決方案後端到裝置應用程式的單向通知。 如需 Azure IoT 中樞所支援之其他雲端到裝置選項的討論,請參閱雲端到裝置的通訊指導方針 (部分機器翻譯)。

注意

本文中所述的功能僅適用於 IoT 中樞的標準層。 如需有關基本和標準/免費 Azure IoT 中樞階層的詳細資訊,請參閱為您的解決方案選擇適合的 Azure IoT 中樞階層

您可以透過面向服務的端點 /messages/devicebound 來傳送雲端到裝置訊息。 裝置接著會透過裝置專用的端點 /devices/{deviceId}/messages/devicebound 來接收訊息。

為了讓每個雲端到裝置訊息都以單一裝置作為目標,您的 IoT 中樞會將 to 屬性設定為 /devices/{deviceId}/messages/devicebound

每個裝置佇列最多保留 50 則雲端到裝置訊息。 如果您嘗試將更多訊息傳送至相同的裝置,則會發生錯誤。

本文討論有關雲端到裝置訊息的概念和程式。 如需開發處理雲端到裝置訊息之應用程式的指引,請參閱 傳送和接收雲端到裝置訊息

雲端到裝置的訊息生命週期

為了保證至少一次訊息傳遞,您的 IoT 中樞會在每個裝置佇列保留雲端到裝置訊息。 在 IoT 中樞從佇列中移除訊息之前,裝置必須明確確認訊息已完成。 此方法保證連線失敗和裝置故障能夠恢復。

生命週期狀態圖表會顯示在下圖中:

此圖顯示雲端到裝置訊息的生命週期狀態圖表。

當 IoT 中樞服務傳送訊息至裝置時,該服務會將訊息狀態設定為「已加入佇列」。 當裝置線程準備好接收訊息時,IoT 中樞會將狀態設定為 [隱藏] 來鎖定訊息。 此狀態可讓裝置上的其他執行緒開始接收其他訊息。 當裝置執行緒完成處理訊息時,它會藉由「完成」訊息來通知 IoT 中樞。 IoT 中樞接著會將狀態設定為「已完成」

裝置也可以︰

  • 「拒絕」訊息,會導致 IoT 中樞將其設定為「無效信件」狀態。 無法復原這些訊息的寄不出的信件佇列。 透過訊息佇列遙測傳輸 (MQTT) 通訊協定連線的裝置無法拒絕雲端到裝置的訊息。

  • 「放棄」訊息,會導致 IoT 中樞將訊息放回佇列,並將狀態設定為「已排入佇列」。 透過 MQTT 通訊協定連線的裝置無法放棄雲端到裝置訊息。

執行緒可能無法處理訊息,且不會通知 IoT 中樞。 在此情況下,訊息會在可見逾時(或鎖定逾時)之後,自動從 不可見 狀態轉換回 加入佇列 狀態。 此逾時的長度為一分鐘,無法變更。

IoT 中樞上的最大傳遞計數屬性會決定訊息可以在「已加入佇列」與「不可見」狀態之間轉換的次數上限。 達到該轉換次數之後,IoT 中樞就會將訊息的狀態設定為「無效信件」。 同樣地,IoT 中樞在訊息的到期時間過後,也會將訊息的狀態設定為「已變更為無效信件」

通常只要遺失訊息不會影響應用程式邏輯,裝置就應該完成雲端到裝置訊息。 此完成的範例可能是當裝置在本機保存訊息內容或已成功執行作業時。 訊息可能也會攜帶暫時性資訊,遺失該訊息並不會影響應用程式的功能。 對於長時間執行的工作,您有時可以:

  • 裝置將工作描述保存於本機儲存體之後,完成雲端到裝置訊息。

  • 在作業進度的各個階段,利用一或多個裝置到雲端訊息來通知解決方案後端。

訊息到期 (存留時間)

每個雲端到裝置的訊息都有到期時間。 此時間由以下選項任一個所設定:

  • 服務中的 ExpiryTimeUtc 屬性
  • IoT 中樞,使用預設的存留時間,其已指定為 IoT 中樞屬性

如需訊息到期的詳細資訊,請參閱雲端到裝置組態選項

利用訊息到期和避免將訊息傳送至已中斷連線裝置的常見方法是設定較短的存留時間值。 這個做法可達到與維護裝置連線狀態相同的效果,但更具效率。 當您要求訊息通知時,IoT 中樞會通知您裝置的狀態為:

  • 能夠接收訊息。
  • 未上線或已失敗。

訊息意見反應

當您傳送雲端到裝置的訊息時,服務可以要求傳遞每則訊息的意見反應 (關於該訊息的最終狀態)。 您可以透過將傳送的雲端到裝置訊息中的 iothub-ack 應用程式屬性設定為以下四個值之一來設定訊息意見反應:

認可屬性值 行為
none 預設。 IoT 中樞不會產生意見反應訊息。
positive 如果雲端到裝置訊息達到「已完成」狀態,IoT 中樞就會產生意見反應訊息。
negative 如果雲端到裝置訊息達到「無效信件」狀態,IoT 中樞就會產生意見反應訊息。
完整 IoT 中樞在任一情況下都會產生意見反應訊息。

如果認可屬性值設為 full,而且您沒有收到意見反應訊息,這表示該意見反應訊息已過期。 服務無法得知原始訊息發生了什麼事。 實際上,服務應該確保它可以在回饋到期之前對其進行處理。 最長到期時間是兩天,因此如果服務發生失敗,您會有充裕的時間可以讓服務再次執行。

端點 (部分機器翻譯) 中所述,IoT 中樞會透過面向服務的端點 (/messages/servicebound/feedback) 利用訊息來傳遞意見反應。 接收意見反應的語意與雲端到裝置訊息的接收語意相同。 可能的話,訊息意見反應會放入單一訊息中,其格式如下:

屬性 說明
EnqueuedTime 指出中樞收到意見反應訊息的時間的時間戳記。
UserId {iot hub name}
ContentType application/vnd.microsoft.iothub.feedback.json

系統會在批次達到 64 則訊息時傳送意見反應,或在上次傳送後 15 秒內傳送意見反應,以時間較近者為優先。

主體是記錄的 JSON 序列化陣列,而每筆記錄都具有下列屬性︰

屬性 說明
enqueuedTimeUtc 指出訊息結果發生時間的時間戳記。 例如,指出中樞何時收到意見反應訊息或原始訊息何時過期的時間戳記。
originalMessageId 此意見反應資訊相關之雲端到裝置訊息的 MessageId
statusCode 必要字串,用於 IoT 中樞所產生的意見反應訊息:
「成功」
已到期
DeliveryCountExceeded
已拒絕
已清除
description StatusCode的字串值。
deviceId 此意見反應資訊相關之雲端到裝置訊息的目標裝置 DeviceId
deviceGenerationId 此意見反應資訊相關之雲端到裝置訊息的目標裝置 DeviceGenerationId

該服務必須指定 MessageId,以便雲端到裝置的訊息可以將其意見反應與原始訊息相互關聯。

下列程式碼範例顯示意見反應訊息的本文:

[
  {
    "originalMessageId": "0987654321",
    "enqueuedTimeUtc": "2015-07-28T16:24:48.789Z",
    "statusCode": "Success",
    "description": "Success",
    "deviceId": "123",
    "deviceGenerationId": "abcdefghijklmnopqrstuvwxyz"
  },
  {
    ...
  },
  ...
]

已刪除裝置的擱置意見反應

刪除裝置時,也會刪除任何擱置的意見反應。 裝置意見反應會以批次傳送。 當裝置確認收到訊息與當準備下一個意見反應批次之間可能會出現一個狹窄的視窗 (通常小於一秒鐘)。 如果在該狹窄的視窗中刪除裝置,則不會出現意見反應。

您可以在刪除裝置之前等候一段時間,等待擱置的意見反應送達,以解決此行為。 刪除裝置後,相關的訊息意見反應應假設遺失。

雲端到裝置組態選項

每個 IoT 中樞都會針對雲端到裝置傳訊公開下列設定選項:

屬性 說明 範圍和預設值
defaultTtlAsIso8601 雲端到裝置訊息的預設 TTL ISO_8601 間隔最長兩天 (最少一分鐘);預設值:一小時
maxDeliveryCount 每個裝置佇列的雲端到裝置最大傳遞計數 1 到 100;預設:10
feedback.ttlAsIso8601 保留服務繫結的意見反應訊息 ISO_8601 間隔最長兩天 (最少一分鐘);預設值:一小時
feedback.maxDeliveryCount 意見反應佇列的最大傳遞計數 1 到 100;預設:10
feedback.lockDurationAsIso8601 鎖定意見反應佇列的持續時間 ISO_8601 間隔 5 到 300 秒 (最少 5 秒);預設值:60 秒。

您可以在 Azure 入口網站 或 Azure CLI 中設定組態選項:

  • Azure 入口網站:在 IoT 中樞的 [中樞設定] 下,選取 [內建端點],接著前往 [雲端到裝置傳訊]。 (Azure 入口網站目前不支援設定 feedback.maxDeliveryCountfeedback.lockDurationAsIso8601 屬性。)

    在入口網站中設定雲端到裝置傳訊的組態選項

  • Azure CLI:使用 az iot hub update 命令:

    az iot hub update --name {your IoT hub name} \
        --set properties.cloudToDevice.defaultTtlAsIso8601=PT1H0M0S
    
    az iot hub update --name {your IoT hub name} \
        --set properties.cloudToDevice.maxDeliveryCount=10
    
    az iot hub update --name {your IoT hub name} \
        --set properties.cloudToDevice.feedback.ttlAsIso8601=PT1H0M0S
    
    az iot hub update --name {your IoT hub name} \
        --set properties.cloudToDevice.feedback.maxDeliveryCount=10
    
    az iot hub update --name {your IoT hub name} \
        --set properties.cloudToDevice.feedback.lockDurationAsIso8601=PT0H1M0S
    

下一步

如需可用來處理雲端到裝置訊息的 SDK 相關信息,請參閱 Azure IoT 中樞 SDK

如需開發處理雲端到裝置訊息之應用程式的指引,請參閱 傳送和接收雲端到裝置訊息