使用 IoT 中樞傳送雲端到裝置訊息 (.NET)

Azure IoT 中樞是一項完全受控的服務,有助於讓數百萬個裝置和一個解決方案後端進行可靠且安全的雙向通訊。

本文示範如何:

  • 透過IoT 中樞,將雲端到裝置 (C2D) 訊息從解決方案後端傳送到單一裝置

  • 接收裝置上的雲端到裝置訊息

  • 從解決方案後端,要求確認收到從 IoT 中樞傳送到裝置的訊息 (意見反應)

注意

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

在本文結尾處,您會執行兩個 .NET 主控台應用程式。

  • MessageReceiveSampleMicrosoft Azure IoT SDK for .NET隨附的範例裝置應用程式,可連線到 IoT 中樞並接收雲端到裝置訊息。

  • SendCloudToDevice:透過 IoT 中樞 將雲端到裝置訊息傳送至裝置應用程式的服務應用程式,然後接收其傳遞通知。

注意

IoT 中樞會透過 Azure IoT 裝置 SDK 為許多裝置平台和語言 (C、Java、Python 及 JavaScript) 提供 SDK 支援。

您可以在使用 IoT 中樞的 D2C 和 C2D 傳訊中,找到有關雲端到裝置訊息的詳細資訊。

必要條件

  • Azure 訂用帳戶。 如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶

  • Azure 訂用帳戶中的 IoT 中樞。 如果您還沒有中樞,可遵循建立 IoT 中樞中的步驟。

  • 在 IoT 中樞內註冊的裝置。 如果您尚未註冊裝置,請在Azure 入口網站中註冊一個裝置。

  • 本文使用 適用于 C# 的 Azure IoT SDK範例程式碼。

    • 從 GitHub 下載或複製 SDK 存放庫到您的開發電腦。
    • 請確定您的開發電腦上已安裝 .NET Core 3.0.0 或更新版本。 視需要執行 dotnet --version下載 .NET 來檢查您的版本。
  • 請確定您的防火牆已開啟連接埠 8883。 本文中的裝置範例會使用 MQTT 通訊協定,其會透過連接埠 8883 進行通訊。 某些公司和教育網路環境可能會封鎖此連接埠。 如需此問題的詳細資訊和解決方法,請參閱連線至 IoT 中樞 (MQTT)

  • Visual Studio。

取得裝置連接字串

在本文中,您會執行模擬裝置的範例應用程式,以接收透過您IoT 中樞傳送的雲端到裝置訊息。 Microsoft Azure IoT SDK for .NET隨附的MessageReceiveSample範例應用程式會連線到 IoT 中樞,並作為模擬裝置。 此範例會使用 IoT 中樞上已註冊裝置的主要連接字串。

若要取得註冊至 IoT 中樞之裝置的主要連接字串,請遵循下列步驟:

  1. Azure 入口網站中選取 [資源群組]。 選取中樞所在的資源群組,然後從資源清單選取中樞。

  2. 在 IoT 中樞的左側窗格的[裝置管理] 底下,選取 [裝置]。

  3. 從裝置清單中,選取適當的裝置。

  4. 複製 [主要連接字串] 並儲存該值。

    此螢幕擷取畫面顯示如何擷取Azure 入口網站中註冊至 IoT 中樞之裝置的主要連接字串。

在裝置應用程式中接收訊息

在本節中,執行 MessageReceiveSample 範例裝置應用程式,以接收透過 IoT 中樞傳送的 C2D 訊息。 開啟新的命令提示字元,並在您展開 Azure IoT C# SDK 的資料夾下,流覽至 azure-iothub\device\samples\getting started\MessageReceiveSample 資料夾。 執行下列命令,將 {Your device connection string} 預留位置值取代為您從 IoT 中樞的已註冊裝置複製的裝置連接字串。

dotnet restore
dotnet run --c "{Your device connection string}"

下列輸出是在成功啟動並聯機到 IoT 中樞之後,來自範例裝置應用程式:

5/22/2023 11:13:18 AM> Press Control+C at any time to quit the sample.
     
5/22/2023 11:13:18 AM> Device waiting for C2D messages from the hub...
5/22/2023 11:13:18 AM> Use the Azure Portal IoT hub blade or Azure IoT Explorer to send a message to this device.
5/22/2023 11:13:18 AM> Trying to receive C2D messages by polling using the ReceiveAsync() method. Press 'n' to move to the next phase.

範例裝置應用程式會使用 ReceiveAsyncCompleteAsync 方法來輪詢訊息。 方法 ReceiveC2dMessagesPollingAndCompleteAsync 會使用 ReceiveAsync 方法,這個方法會在裝置收到訊息時以非同步方式傳回已接收的訊息。 ReceiveAsync 在可指定逾時期間之後傳回 null 。 在此範例中,使用的是預設值一分鐘。 當裝置收到 Null時,它應該會繼續等候新的訊息。 此需求是範例應用程式在 方法中包含 ReceiveC2dMessagesPollingAndCompleteAsync 下列程式碼區塊的原因:

   if (receivedMessage == null)
   {
      continue;
   }

方法的 CompleteAsync 呼叫會通知IoT 中樞訊息已成功處理,而且可以從裝置佇列安全地移除訊息。 無論使用的通訊協定為何,裝置在處理順利完成時,應該呼叫此方法。

透過 AMQP 和 HTTPS 通訊協定,但不是 MQTT 通訊協定,裝置也可以:

  • 放棄訊息,這會使得 IoT 中樞將訊息保留在裝置佇列中以供未來使用。
  • 拒絕訊息,這會永久移除裝置佇列中的訊息。

如果發生導致裝置無法完成、放棄或拒絕訊息的情況,IoT 中樞在固定的逾時期間之後,會將訊息排入佇列以再次傳遞。 基於這個原因,裝置應用程式中的訊息處理邏輯必須是「等冪」,如此一來,多次接收相同訊息才會產生相同的結果。

如需雲端到裝置訊息生命週期及 IoT 中樞如何處理雲端到裝置訊息的詳細資訊,請參閱從 IoT 中樞傳送雲端到裝置訊息

注意

使用 HTTPS 而不使用 MQTT 或 AMQP 作為傳輸時,ReceiveAsync 方法會立即傳回。 使用 HTTPS 時,針對雲端到裝置訊息支援的模式是裝置以間歇方式連接而不常檢查訊息 (至少每 25 分鐘一次)。 發出更多 HTTPS 接收會導致「IoT 中樞」對要求進行節流。 如需 MQTT、AMQP 和 HTTPS 支援之間差異的詳細資訊,請參閱雲端到裝置的通訊指引選擇通訊協定

取得 IoT 中樞連接字串

在本文中,您會建立後端服務,以透過您的 IoT 中樞傳送雲端到裝置訊息。 若要傳送雲端到裝置訊息,則服務需要服務連線權限。 根據預設,每個 IoT 中樞都是透過授與此權限且名為服務的共用存取原則所建立。

若要取得服務原則的 IoT 中樞連接字串,請遵循下列步驟:

  1. Azure 入口網站中選取 [資源群組]。 選取中樞所在的資源群組,然後從資源清單選取中樞。

  2. 在 IoT 中樞的左側窗格中,選取 [共用存取原則]。

  3. 從原則清單中,選取服務原則。

  4. 複製 [主要連接字串] 並儲存該值。

顯示如何從您在 Azure 入口網站中的 IoT 中樞擷取連接字串的螢幕擷取畫面。

如需 IoT 中樞共用存取原則和權限的詳細資訊,請參閱存取控制及權限

傳送雲端到裝置訊息

在本節中,您會建立 .NET 主控台應用程式,以將雲端到裝置訊息傳送給模擬裝置應用程式。 您需要來自裝置的裝置識別碼和 IoT 中樞連接字串。

  1. 在 Visual Studio 中,選取 [檔案]> [新增]> [專案]。 在 [建立新專案] 中,選取 [主控台應用程式 (.NET Framework)],然後選取 [下一步]。

  2. 將專案命名為 SendCloudToDevice,然後選取 [下一步]。

    Visual Studio 中 [設定您的新專案] 快顯視窗的螢幕擷取畫面。

  3. 接受最新版本的 .NET Framework。 選取 [Create] \(建立\) 以建立專案。

  4. 在 [方案總管] 中,以滑鼠右鍵按一下新的專案,然後選取 [管理 NuGet 套件]。

  5. 在 [管理 NuGet 套件] 中,選取 [瀏覽],然後搜尋並選取 [Microsoft.Azure.Devices]。 選取 [安裝]。

    此步驟會下載和安裝 Azure IoT 服務 SDK NuGet 套件,並新增其參考。

  6. Program.cs 檔案開頭處新增下列 using 陳述式。

    using Microsoft.Azure.Devices;
    
  7. 將下列欄位新增到 Program 類別。 將 {iot hub connection string} 預留位置值取代為先前在取得 IoT 中樞連接字串內記下的 IoT 中樞連接字串。 將 {device id} 預留位置值取代為 IoT 中樞中已註冊裝置的裝置識別碼。

    static ServiceClient serviceClient;
    static string connectionString = "{iot hub connection string}";
    static string targetDevice = "{device id}";
    
  8. 將下列方法新增至 Program 類別,藉以將訊息傳送至您的裝置。

    private async static Task SendCloudToDeviceMessageAsync()
    {
         var commandMessage = new
          Message(Encoding.ASCII.GetBytes("Cloud to device message."));
         await serviceClient.SendAsync(targetDevice, commandMessage);
    }
    
  9. 最後,將下列幾行新增到 Main 方法中。

    Console.WriteLine("Send Cloud-to-Device message\n");
    serviceClient = ServiceClient.CreateFromConnectionString(connectionString);
    
    Console.WriteLine("Press any key to send a C2D message.");
    Console.ReadLine();
    SendCloudToDeviceMessageAsync().Wait();
    Console.ReadLine();
    
  10. F5 以啟動範例服務應用程式。 選取 [SendCloudToDevice] 視窗,然後按下 Enter。 您應該會看到範例裝置應用程式收到的訊息,如下列輸出範例所示。

    5/22/2023 11:13:18 AM> Press Control+C at any time to quit the sample.
    
    5/22/2023 11:13:18 AM> Device waiting for C2D messages from the hub...
    5/22/2023 11:13:18 AM> Use the Azure Portal IoT hub blade or Azure IoT Explorer to send a message to this device.
    5/22/2023 11:13:18 AM> Trying to receive C2D messages by polling using the ReceiveAsync() method. Press 'n' to move to the next phase.
    5/22/2023 11:15:18 AM> Polling using ReceiveAsync() - received message with Id=
    5/22/2023 11:15:18 AM> Received message: [Cloud to device message.]
            Content type:
    
    5/22/2023 11:15:18 AM> Completed C2D message with Id=.
    

接收傳遞意見反應

您可向 IoT 中樞要求每個雲端到裝置訊息的傳遞 (或到期) 通知。 這個選項可讓解決方案後端輕鬆地通知、重試或補償邏輯。 如需有關雲端到裝置意見反應的詳細資訊,請參閱使用 IoT 中樞的 D2C 和 C2D 傳訊

在本節中,您會修改 SendCloudToDevice 範例服務應用程式來要求意見反應,並從 IoT 中樞接收。

  1. 在 Visual Studio 的 SendCloudToDevice 專案中,將下列方法加入至 Program 類別。

    private async static void ReceiveFeedbackAsync()
    {
         var feedbackReceiver = serviceClient.GetFeedbackReceiver();
    
         Console.WriteLine("\nReceiving c2d feedback from service");
         while (true)
         {
             var feedbackBatch = await feedbackReceiver.ReceiveAsync();
             if (feedbackBatch == null) continue;
    
             Console.ForegroundColor = ConsoleColor.Yellow;
             Console.WriteLine("Received feedback: {0}",
               string.Join(", ", feedbackBatch.Records.Select(f => f.StatusCode)));
             Console.ResetColor();
    
             await feedbackReceiver.CompleteAsync(feedbackBatch);
         }
     }
    

    請注意,此接收模式與用來從裝置應用程式接收雲端到裝置訊息的模式相同。

  2. 將下列行新增至 Main 方法中的 serviceClient = ServiceClient.CreateFromConnectionString(connectionString) 之後。

    ReceiveFeedbackAsync();
    
  3. 為了要求雲端到裝置訊息傳遞狀況的意見反應,您必須在 SendCloudToDeviceMessageAsync 方法中指定屬性。 將下列行新增至 var commandMessage = new Message(...); 行之後。

    commandMessage.Ack = DeliveryAcknowledgement.Full;
    
  4. 請確定範例裝置應用程式正在執行,然後按 F5執行範例服務應用程式。 選取 SendCloudToDevice 主控台視窗,然後按 Enter鍵。 您應該會看到範例裝置應用程式收到訊息,並在幾秒鐘後, 您的 SendCloudToDevice 應用程式收到意見反應訊息。 下列輸出顯示範例服務應用程式所收到的意見反應訊息:

    Send Cloud-to-Device message
    
    
    Receiving c2d feedback from service
    Press any key to send a C2D message.
    
    Received feedback: Success
    

注意

為了簡單起見,本文不會實作任何重試原則。 在生產程式碼中,您應該如 暫時性錯誤處理中所建議來實作重試原則 (例如指數輪詢)。

後續步驟

在本文中,您已了解如何傳送和接收雲端到裝置的訊息。