Share via


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

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

注意

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

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

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

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

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

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

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

Diagram showing the life-cycle state graph of cloud-to-device messages.

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

裝置也可以︰

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

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

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

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

Set configuration options for cloud-to-device messaging in the portal

  • 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

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