從 IoT 中樞傳送雲端到裝置訊息

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

注意

本文中所述的功能僅適用於 IoT 中樞的標準層。 如需基本和標準/免費IoT 中樞層的詳細資訊,請參閱為您的解決方案選擇正確的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 中樞在訊息的到期時間過後,也會將訊息的狀態設定為「已變更為無效信件」。 如需詳細資訊,請參閱存留時間 (部分機器翻譯)。

如何使用 IoT 中樞傳送雲端到裝置訊息 (部分機器翻譯) 文章會示範如何從雲端傳送雲端到裝置訊息,並在裝置上接收它們。

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

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

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

訊息到期 (存留時間)

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

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

請參閱雲端到裝置的設定選項

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

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

訊息意見反應

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

認可屬性值 行為
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"
  },
  {
    ...
  },
  ...
]

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

刪除裝置時,也會刪除任何擱置的意見反應。 裝置意見反應會以批次傳送。 如果在裝置確認收到訊息和準備下一批意見反應之間的極短時間範圍內 (通常小於 1 秒) 刪除裝置,將不會發生意見反應。

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

雲端到裝置組態選項

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

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

您可以利用下列其中一種方式設定組態選項:

  • 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 (部分機器翻譯)。

若要嘗試接收雲端到裝置訊息,請參閱傳送雲端到裝置教學課程。