使用 IoT 中心发送云到设备的消息 (Java)Send cloud-to-device messages with IoT Hub (Java)

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 simulated device app that sends device-to-cloud messages.

Note

本文介绍的功能仅在 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:

  • 通过 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 中心开发人员指南中找到有关云到设备消息的详细信息。You can find more information on cloud-to-device messages in the IoT Hub developer guide.

在本教程的最后,会运行两个 Java 控制台应用:At the end of this tutorial, you run two Java console apps:

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

  • send-c2d-messages,它将“云到设备”消息通过 IoT 中心发送到模拟设备应用,并接收 IoT 中心的送达确认。send-c2d-messages, which sends a cloud-to-device message to the simulated device app through IoT Hub, and then receives its delivery acknowledgement.

Note

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 中心的分步说明,请参阅 Azure 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 Azure IoT Developer Center.

先决条件Prerequisites

在模拟设备应用上接收消息Receive messages in the simulated device app

在本部分中,将修改在从设备将遥测数据发送到 IoT 中心中创建的模拟设备应用,以接收来自 IoT 中心的云到设备消息。In this section, you modify the simulated 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. 使用文本编辑器打开 simulated-device\src\main\java\com\mycompany\app\App.java 文件。Using a text editor, open the simulated-device\src\main\java\com\mycompany\app\App.java file.

  2. App 类中添加以下 MessageCallback 类作为嵌套类。Add the following MessageCallback class as a nested class inside the App class. 设备从 IoT 中心接收消息时,将调用 execute 方法。The execute method is invoked when the device receives a message from IoT Hub. 在本示例中,设备始终通知 IoT 中心它已完成消息:In this example, the device always notifies the IoT hub that it has completed the message:

    private static class AppMessageCallback implements MessageCallback {
      public IotHubMessageResult execute(Message msg, Object context) {
        System.out.println("Received message from hub: "
          + new String(msg.getBytes(), Message.DEFAULT_IOTHUB_MESSAGE_CHARSET));
    
        return IotHubMessageResult.COMPLETE;
      }
    }
    
  3. 修改 main 方法,以创建 AppMessageCallback 实例,并在打开客户端之前调用 setMessageCallback 方法,如下所示:Modify the main method to create an AppMessageCallback instance and call the setMessageCallback method before it opens the client as follows:

    client = new DeviceClient(connString, protocol);
    
    MessageCallback callback = new AppMessageCallback();
    client.setMessageCallback(callback, null);
    client.open();
    

    Note

    如果使用 HTTPS(而不使用 MQTT 或 AMQP)作为传输,则 DeviceClient 实例将不会频繁(频率低于每 25 分钟一次)检查 IoT 中心发来的消息。If you use HTTPS instead of MQTT or AMQP as the transport, the DeviceClient instance checks for messages from IoT Hub infrequently (less than every 25 minutes). 有关 MQTT、AMQP 和 HTTPS 支持之间的差异,以及 IoT 中心限制的详细信息,请参阅 IoT 中心开发人员指南的消息传递部分For more information about the differences between MQTT, AMQP and HTTPS support, and IoT Hub throttling, see the messaging section of the IoT Hub developer guide.

  4. 若要使用 Maven 构建 simulated-device 应用,请在 simulated-device 文件夹的命令提示符处执行以下命令:To build the simulated-device app using Maven, execute the following command at the command prompt in the simulated-device folder:

    mvn clean package -DskipTests
    

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

在本文中,你将创建一项后端服务,用于通过你在将遥测数据从设备发送到 IoT 中心中创建的 IoT 中心发送云到设备消息。In this article you create a backend 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

在本部分中,会创建 Java 控制台应用,用于向模拟设备应用发送“云到设备”消息。In this section, you create a Java console app that sends cloud-to-device messages to the simulated device app. 需要在从设备将遥测数据发送到 IoT 中心快速入门中添加的设备的设备 ID。You need the device ID of the device you added in the Send telemetry from a device to an IoT hub quickstart. 还需要先前在获取 IoT 中心连接字符串中复制的 IoT 中心连接字符串。You also need the the IoT hub connection string you copied previously in Get the IoT hub connection string.

  1. 在命令提示符处使用以下命令,创建名为 send-c2d-messages 的 Maven 项目。Create a Maven project called send-c2d-messages using the following command at your command prompt. 请注意,此命令是一条很长的命令:Note this command is a single, long command:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=send-c2d-messages -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  2. 在命令提示符下,导航到新的 send-c2d-messages 文件夹。At your command prompt, navigate to the new send-c2d-messages folder.

  3. 使用文本编辑器,打开 send-c2d-messages 文件夹中的 pom.xml 文件,并在 dependencies 节点中添加以下依赖项。Using a text editor, open the pom.xml file in the send-c2d-messages folder and add the following dependency to the dependencies node. 这样即可使用应用程序中的 iothub-java-service-client 包来与 IoT 中心服务通信:Adding the dependency enables you to use the iothub-java-service-client package in your application to communicate with your IoT hub service:

    <dependency>
      <groupId>com.microsoft.azure.sdk.iot</groupId>
      <artifactId>iot-service-client</artifactId>
      <version>1.7.23</version>
    </dependency>
    

    Note

    可以使用 Maven 搜索检查是否有最新版本的 iot-service-clientYou can check for the latest version of iot-service-client using Maven search.

  4. 保存并关闭 pom.xml 文件。Save and close the pom.xml file.

  5. 使用文本编辑器打开 send-c2d-messages\src\main\java\com\mycompany\app\App.java 文件。Using a text editor, open the send-c2d-messages\src\main\java\com\mycompany\app\App.java file.

  6. 在该文件中添加以下 import 语句:Add the following import statements to the file:

    import com.microsoft.azure.sdk.iot.service.*;
    import java.io.IOException;
    import java.net.URISyntaxException;
    
  7. 将以下类级变量添加到 App 类,并将 {yourhubconnectionstring}{yourdeviceid} 替换为前面记下的值:Add the following class-level variables to the App class, replacing {yourhubconnectionstring} and {yourdeviceid} with the values you noted earlier:

    private static final String connectionString = "{yourhubconnectionstring}";
    private static final String deviceId = "{yourdeviceid}";
    private static final IotHubServiceClientProtocol protocol =    
        IotHubServiceClientProtocol.AMQPS;
    
  8. main方法替换为以下代码。Replace the main method with the following code. 此代码用于连接到 IoT 中心,将消息发送到设备,并等待设备已接收并处理消息的通知:This code connects to your IoT hub, sends a message to your device, and then waits for an acknowledgment that the device received and processed the message:

    public static void main(String[] args) throws IOException,
        URISyntaxException, Exception {
      ServiceClient serviceClient = ServiceClient.createFromConnectionString(
        connectionString, protocol);
    
      if (serviceClient != null) {
        serviceClient.open();
        FeedbackReceiver feedbackReceiver = serviceClient
          .getFeedbackReceiver();
        if (feedbackReceiver != null) feedbackReceiver.open();
    
        Message messageToSend = new Message("Cloud to device message.");
        messageToSend.setDeliveryAcknowledgement(DeliveryAcknowledgement.Full);
    
        serviceClient.send(deviceId, messageToSend);
        System.out.println("Message sent to device");
    
        FeedbackBatch feedbackBatch = feedbackReceiver.receive(10000);
        if (feedbackBatch != null) {
          System.out.println("Message feedback received, feedback time: "
            + feedbackBatch.getEnqueuedTimeUtc().toString());
        }
    
        if (feedbackReceiver != null) feedbackReceiver.close();
        serviceClient.close();
      }
    }
    

    Note

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

  9. 若要使用 Maven 构建 simulated-device 应用,请在 simulated-device 文件夹的命令提示符处执行以下命令:To build the simulated-device app using Maven, execute the following command at the command prompt in the simulated-device folder:

    mvn clean package -DskipTests
    

    运行应用程序Run the applications

    现在,已准备就绪,可以运行应用程序了。You are now ready to run the applications.

  10. 在 simulated-device 文件夹的命令提示符处,运行以下命令以发送遥测数据至 IoT 中心并侦听中心发出的云到设备消息:At a command prompt in the simulated-device folder, run the following command to begin sending telemetry to your IoT hub and to listen for cloud-to-device messages sent from your hub:

    mvn exec:java -Dexec.mainClass="com.mycompany.app.App" 
    

    运行模拟设备应用

  11. 在 send-c2d-messages 文件夹的命令提示符处,运行以下命令以发送云到设备的消息并等待反馈确认:At a command prompt in the send-c2d-messages folder, run the following command to send a cloud-to-device message and wait for a feedback acknowledgment:

    mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
    

    运行命令以发送“云到设备”消息

后续步骤Next steps

在本教程中,已学习如何发送和接收云到设备的消息。In this tutorial, 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.