使用 IoT 中心 (.NET) 将消息从云发送到设备Send messages from the cloud to your device with IoT Hub (.NET)

Azure IoT 中心是一项完全托管的服务,有助于在数百万台设备和单个解决方案后端之间实现安全可靠的双向通信。Azure IoT Hub is a fully managed service that helps enable reliable and secure bi-directional communications between millions of devices and a solution back end. 从设备将遥测数据发送到 IoT 中心快速入门介绍了如何创建 IoT 中心、在其中预配设备标识,以及编写设备应用来发送设备到云的消息。The Send telemetry from a device to an IoT hub quickstart shows how to create an IoT hub, provision a device identity in it, and code a device app that sends device-to-cloud messages.

备注

本文介绍的功能仅在 IoT 中心的标准层中可用。The features described in this article are available only in the standard tier of IoT Hub. 有关基本和标准/免费 IoT 中心层的详细信息,请参阅选择合适的 IoT 中心层For more information about the basic and standard/free IoT Hub tiers, see Choose the right IoT Hub tier.

本教程在从设备将遥测数据发送到 IoT 中心的基础上编写。This tutorial builds on Send telemetry from a device to an IoT hub. 它展示了如何执行以下任务:It shows you how to do the following tasks:

  • 通过 IoT 中心,将云到设备的消息从解决方案后端发送到单个设备。From your solution back end, send cloud-to-device messages to a single device through IoT Hub.
  • 在设备上接收云到设备的消息。Receive cloud-to-device messages on a device.
  • 通过解决方案后端,请求确认收到从 IoT 中心发送到设备的消息(反馈 )。From your solution back end, request delivery acknowledgement (feedback) for messages sent to a device from IoT Hub.

可以在 IoT 中心的 D2C 和 C2D 消息传送中找到有关“云到设备”消息的详细信息。You can find more information on cloud-to-device messages in D2C and C2D Messaging with IoT Hub.

在本教程结束时,会运行 2 个 .NET 控制台应用。At the end of this tutorial, you run two .NET console apps.

  • SimulatedDeviceSimulatedDevice. 此应用连接到 IoT 中心并接收云到设备的消息。This app connects to your IoT hub and receives cloud-to-device messages. 此应用是在从设备将遥测数据发送到 IoT 中心中创建的应用的修改版本。This app is a modified version of the app created in Send telemetry from a device to an IoT hub.

  • SendCloudToDeviceSendCloudToDevice. 此应用通过 IoT 中心将云到设备的消息发送到设备应用,然后接收中心的传送确认。This app sends a cloud-to-device message to the device app through IoT Hub, and then receives its delivery acknowledgment.

备注

IoT 中心通过 Azure IoT 设备 SDK 对许多设备平台和语言(包括 C、Java、Python 和 Javascript)提供 SDK 支持。IoT Hub has SDK support for many device platforms and languages, including C, Java, Python, and Javascript, through Azure IoT device SDKs. 有关如何将设备连接到本教程的代码以及通常如何连接到 Azure IoT 中心的分步说明,请参阅 IoT 中心开发人员指南For step-by-step instructions on how to connect your device to this tutorial's code, and generally to Azure IoT Hub, see the IoT Hub developer guide.

先决条件Prerequisites

  • Visual StudioVisual Studio

  • 有效的 Azure 帐户。An active Azure account. (如果没有帐户,只需几分钟即可创建一个试用帐户。)(If you don't have an account, you can create a trial account in just a couple of minutes.)

  • 确保已在防火墙中打开端口 8883。Make sure that port 8883 is open in your firewall. 本文中的设备示例使用 MQTT 协议,该协议通过端口 8883 进行通信。The device sample in this article uses MQTT protocol, which communicates over port 8883. 在某些公司和教育网络环境中,此端口可能被阻止。This port may be blocked in some corporate and educational network environments. 有关解决此问题的更多信息和方法,请参阅连接到 IoT 中心(MQTT)For more information and ways to work around this issue, see Connecting to IoT Hub (MQTT).

在设备应用中接收消息Receive messages in the device app

在本部分中,请修改在从设备将遥测数据发送到 IoT 中心中创建的设备应用,以接收来自 IoT 中心的云到设备消息。In this section, modify the device app you created in Send telemetry from a device to an IoT hub to receive cloud-to-device messages from the IoT hub.

  1. 在 Visual Studio 的 SimulatedDevice 项目中,将以下方法添加到 Program 类。In Visual Studio, in the SimulatedDevice project, add the following method to the Program class.

     private static async void ReceiveC2dAsync()
     {
         Console.WriteLine("\nReceiving cloud to device messages from service");
         while (true)
         {
             Message receivedMessage = await s_deviceClient.ReceiveAsync();
             if (receivedMessage == null) continue;
    
             Console.ForegroundColor = ConsoleColor.Yellow;
             Console.WriteLine("Received message: {0}", 
             Encoding.ASCII.GetString(receivedMessage.GetBytes()));
             Console.ResetColor();
    
             await s_deviceClient.CompleteAsync(receivedMessage);
         }
     }
    
  2. Main 方法中的 Console.ReadLine() 行前面添加以下方法:Add the following method in the Main method, right before the Console.ReadLine() line:

    ReceiveC2dAsync();
    

在设备收到消息时,ReceiveAsync 方法以异步方式返回收到的消息。The ReceiveAsync method asynchronously returns the received message at the time that it is received by the device. 它在可指定的超时期限过后返回 nullIt returns null after a specifiable timeout period. 在本示例中,使用的是默认值一分钟。In this example, the default of one minute is used. 当应用收到 null 时,它应继续等待新消息。When the app receives a null, it should continue to wait for new messages. 此要求是使用 if (receivedMessage == null) continue 行的原因。This requirement is the reason for the if (receivedMessage == null) continue line.

CompleteAsync() 的调用通知 IoT 中心,指出已成功处理消息。The call to CompleteAsync() notifies IoT Hub that the message has been successfully processed. 可以安全地从设备队列中删除该消息。The message can be safely removed from the device queue. 如果因故导致设备应用无法完成消息处理操作,IoT 中心将重新传送该消息。If something happened that prevented the device app from completing the processing of the message, IoT Hub delivers it again. 设备应用中的消息处理逻辑必须是幂等的 ,这样多次接收相同的消息才会生成相同的结果。The message processing logic in the device app must be idempotent, so that receiving the same message multiple times produces the same result.

应用程序也可以暂时放弃消息,让 IoT 中心将消息保留在队列中以供将来使用。An application can also temporarily abandon a message, which results in IoT hub retaining the message in the queue for future consumption. 或者,应用程序可以拒绝消息,以永久性从队列中删除该消息。Or the application can reject a message, which permanently removes the message from the queue. 有关云到设备消息生命周期的详细信息,请参阅 IoT 中心的 D2C 和 C2D 消息传送For more information about the cloud-to-device message lifecycle, see D2C and C2D messaging with IoT Hub.

备注

使用 HTTPS 而不使用 MQTT 或 AMQP 作为传输时,ReceiveAsync 方法将立即返回。When using HTTPS instead of MQTT or AMQP as a transport, the ReceiveAsync method returns immediately. 使用 HTTPS 的云到设备消息,其支持模式是间歇连接到设备,且不常检查消息(时间间隔小于 25 分钟)。The supported pattern for cloud-to-device messages with HTTPS is intermittently connected devices that check for messages infrequently (less than every 25 minutes). 发出更多 HTTPS 接收会导致 IoT 中心限制请求。Issuing more HTTPS receives results in IoT Hub throttling the requests. 有关 MQTT、AMQP 和 HTTPS 支持之间的差异,以及 IoT 中心限制的详细信息,请参阅 IoT 中心的 D2C 和 C2D 消息传送For more information about the differences between MQTT, AMQP and HTTPS support, and IoT Hub throttling, see D2C and C2D messaging with IoT Hub.

获取 IoT 中心连接字符串Get the IoT Hub connection string

在本文中,你将创建一项后端服务,用于通过你在将遥测数据从设备发送到 IoT 中心中创建的 IoT 中心发送云到设备消息。In this article, you create a back-end service to send cloud-to-device messages through the IoT hub you created in Send telemetry from a device to an IoT hub. 若要发送云到设备消息,服务需要“服务连接”权限。 To send cloud-to-device messages, your service needs the service connect permission. 默认情况下,每个 IoT 中心都使用名为 service 的共享访问策略创建,该策略授予此权限。By default, every IoT Hub is created with a shared access policy named service that grants this permission.

若要获取 service 策略的 IoT 中心连接字符串,请执行以下步骤:To get the IoT Hub connection string for the service policy, follow these steps:

  1. Azure 门户中,选择“资源组” 。In the Azure portal, select Resource groups. 选择中心所在的资源组,然后从资源列表中选择中心。Select the resource group where your hub is located, and then select your hub from the list of resources.

  2. 在 IoT 中心的左侧窗格中,选择“共享访问策略” 。On the left-side pane of your IoT hub, select Shared access policies.

  3. 从策略列表中选择“service” 策略。From the list of policies, select the service policy.

  4. 在“共享访问密钥” 下,选择“连接字符串 - 主密钥” 所对应的“复制”图标并保存该值。Under Shared access keys, select the copy icon for the Connection string -- primary key and save the value.

    显示如何检索连接字符串

有关 IoT 中心共享访问策略和权限的详细信息,请参阅访问控制和权限For more information about IoT Hub shared access policies and permissions, see Access control and permissions.

发送云到设备的消息Send a cloud-to-device message

现在,请编写 .NET 控制台应用,以向设备应用发送云到设备消息。Now you write a .NET console app that sends cloud-to-device messages to the device app.

  1. 在当前的 Visual Studio 解决方案中,选择“文件” > “新建” > “项目” 。In the current Visual Studio solution, select File > New > Project. 在“创建新项目”中,选择“控制台应用(.NET Framework)”,然后选择“下一步” 。In Create a new project, select Console App (.NET Framework), and then select Next.

  2. 将项目命名为 SendCloudToDeviceName the project SendCloudToDevice. 在“解决方案”下选择“添加到解决方案”, 然后接受最新版 .NET Framework。Under Solution, select Add to solution and accept the most recent version of the .NET Framework. 选择“创建” 来创建项目。Select Create to create the project.

    在 Visual Studio 中配置新项目

  3. 在“解决方案资源管理器”中,右键单击新解决方案,然后选择“管理 NuGet 包” 。In Solution Explorer, right-click the new solution, and then select Manage NuGet Packages.

  4. 在“管理 NuGet 包” 中,选择“浏览” ,然后搜索并选择“Microsoft.Azure.Devices” 。In Manage NuGet Packages, select Browse, and then search for and select Microsoft.Azure.Devices. 选择“安装” 。Select Install.

    此步骤会下载、安装 Azure IoT 服务 SDK NuGet 包并添加对它的引用。This step downloads, installs, and adds a reference to the Azure IoT service SDK NuGet package.

  5. Program.cs 文件顶部添加以下 using 语句。Add the following using statement at the top of the Program.cs file.

    using Microsoft.Azure.Devices;
    
  6. 将以下字段添加到 Program 类。Add the following fields to the Program class. 将占位符值替换为先前在获取 IoT 中心连接字符串中复制的 IoT 中心连接字符串。Replace the placeholder value with the IoT hub connection string you copied previously in Get the IoT hub connection string.

    static ServiceClient serviceClient;
    static string connectionString = "{iot hub connection string}";
    
  7. 将以下方法添加到 Program 类。Add the following method to the Program class. 将设备名称设置为在从设备将遥测数据发送到 IoT 中心中定义设备时使用的名称。Set the device name to what you used when defining the device in Send telemetry from a device to an IoT hub.

    private async static Task SendCloudToDeviceMessageAsync()
    {
         var commandMessage = new 
          Message(Encoding.ASCII.GetBytes("Cloud to device message."));
         await serviceClient.SendAsync("myFirstDevice", commandMessage);
    }
    

    此方法会将新的云到设备消息发送到 ID 为 myFirstDevice 的设备。This method sends a new cloud-to-device message to the device with the ID, myFirstDevice. 仅当修改了从设备将遥测数据发送到 IoT 中心中使用的参数,才更改此参数。Change this parameter only if you modified it from the one used in Send telemetry from a device to an IoT hub.

  8. 最后,在 Main 方法中添加以下行。Finally, add the following lines to the Main method.

    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();
    
  9. 在解决方案资源管理器中,右键单击解决方案并选择“设置启动项目”。 In Solutions Explorer, right-click your solution, and select Set StartUp Projects.

  10. 在“常见属性” > “启动项目”中,选择“多个启动项目”, 然后针对 ReadDeviceToCloudMessagesSimulatedDeviceSendCloudToDevice 选择“启动”操作。In Common Properties > Startup Project, select Multiple startup projects, then select the Start action for ReadDeviceToCloudMessages, SimulatedDevice, and SendCloudToDevice. 选择“确定” 保存更改。Select OK to save your changes.

  11. F5Press F5. 这三个应用程序应该都会启动。All three applications should start. 选择“SendCloudToDevice”窗口并按 EnterSelect the SendCloudToDevice windows, and press Enter. 应会看到设备应用正在接收的消息。You should see the message being received by the device app.

    应用接收消息

接收送达反馈Receive delivery feedback

可以从 IoT 中心请求每个云到设备消息的送达(或过期)确认。It is possible to request delivery (or expiration) acknowledgements from IoT Hub for each cloud-to-device message. 借助此选项,解决方案后端能够轻松地通知重试或补偿逻辑。This option enables the solution back end to easily inform retry or compensation logic. 有关云到设备反馈的详细信息,请参阅 IoT 中心的 D2C 和 C2D 消息传送For more information about cloud-to-device feedback, see D2C and C2D Messaging with IoT Hub.

在本部分中,修改 SendCloudToDevice 应用以请求反馈,并接收来自 IoT 中心的反馈。In this section, you modify the SendCloudToDevice app to request feedback, and receive it from the IoT hub.

  1. 在 Visual Studio 中的 SendCloudToDevice 项目内,将以下方法添加到 Program 类。In Visual Studio, in the SendCloudToDevice project, add the following method to the Program class.

    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);
         }
     }
    

    请注意,此接收模式与用于从设备应用接收云到设备消息的模式相同。Note this receive pattern is the same one used to receive cloud-to-device messages from the device app.

  2. Main 方法中的 serviceClient = ServiceClient.CreateFromConnectionString(connectionString) 后面添加以下行。Add the following line in the Main method, right after serviceClient = ServiceClient.CreateFromConnectionString(connectionString).

    ReceiveFeedbackAsync();
    
  3. 若要请求针对传递云到设备消息的反馈,必须在 SendCloudToDeviceMessageAsync 方法中指定一个属性。To request feedback for the delivery of your cloud-to-device message, you have to specify a property in the SendCloudToDeviceMessageAsync method. 紧接在 var commandMessage = new Message(...); 行的后面添加以下行。Add the following line, right after the var commandMessage = new Message(...); line.

    commandMessage.Ack = DeliveryAcknowledgement.Full;
    
  4. F5运行应用。Run the apps by pressing F5. 应会看到三个应用程序都会启动。You should see all three applications start. 选择“SendCloudToDevice”窗口并按 EnterSelect the SendCloudToDevice windows, and press Enter. 应会看到设备应用正在接收的消息,几秒钟后,SendCloudToDevice 应用程序将收到反馈消息。You should see the message being received by the device app, and after a few seconds, the feedback message being received by your SendCloudToDevice application.

    应用接收消息

备注

为简单起见,本教程不实现任何重试策略。For simplicity, this tutorial does not implement any retry policy. 在生产代码中,应该按暂时性故障处理中所述实施重试策略(例如指数退避)。In production code, you should implement retry policies (such as exponential backoff), as suggested in Transient Fault Handling.

后续步骤Next steps

本操作说明已介绍了如何发送和接收云到设备的消息。In this how-to, you learned how to send and receive cloud-to-device messages.

若要了解有关使用 IoT 中心开发解决方案的详细信息,请参阅 IoT 中心开发人员指南To learn more about developing solutions with IoT Hub, see the IoT Hub developer guide.