使用 IoT 中心发送云到设备的消息 (Java)

Azure IoT 中心是一项完全托管的服务,有助于在数百万台设备和单个解决方案后端之间实现安全可靠的双向通信。

本文介绍如何:

  • 通过 IoT 中心,将云到设备的消息从解决方案后端发送到单个设备

  • 在设备上接收云到设备的消息

  • 从解决方案后端,请求送达确认,确认收到从 IoT 中心发送到设备的消息(反馈)

注意

本文所述的功能只能用于 IoT 中心的标准层。 有关 IoT 中心基本层和标准/免费层的详细信息,请参阅选择适合你的解决方案的 IoT 中心层

在本文结束时,会运行两个 Java 控制台应用:

  • SimulatedDevice:从设备将遥测数据发送到 IoT 中心中创建的应用的修改版本,它连接到 IoT 中心并接收云到设备的消息。

  • SendCloudToDevice:它通过 IoT 中心将云到设备消息发送到设备应用,然后接收其送达确认。

注意

IoT 中心通过 Azure IoT 设备 SDK 对许多设备平台和语言(C、Java、Python 和 JavaScript)提供 SDK 支持

若要详细了解云到设备的消息,请参阅从 IoT 中心发送云到设备的消息

先决条件

在模拟设备应用上接收消息

在本部分,修改设备应用,使其从 IoT 中心接收云到设备消息。

  1. 使用文本编辑器打开 simulated-device\src\main\java\com\mycompany\app\App.java 文件。

  2. App 类中添加以下 MessageCallback 类作为嵌套类。 设备从 IoT 中心接收消息时,将调用 execute 方法。 在本示例中,设备始终通知 IoT 中心它已完成消息:

    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 方法,如下所示:

    client = new DeviceClient(connString, protocol);
    
    MessageCallback callback = new AppMessageCallback();
    client.setMessageCallback(callback, null);
    client.open();
    
  4. 若要使用 Maven 生成 simulated-device 应用,请在 simulated-device 文件夹中的命令提示符下执行以下命令:

    mvn clean package -DskipTests
    

AppMessageCallback 类中的 execute 方法会返回 IotHubMessageResult.COMPLETE。 这会通知 IoT 中心,指出已成功处理消息,可以安全地从设备队列中删除该消息了。 无论使用何种协议,设备都会在处理成功完成后返回此值。

使用 AMQP 和 HTTPS,但不使用 MQTT,该设备还可以:

  • 放弃消息,使 IoT 中心将消息保留在设备队列中供将来使用。
  • 拒绝消息,这会永久地从设备队列中删除该消息。

如果发生阻止设备完成、放弃或拒绝消息的情况,IoT 中心会在固定的超时期限过后再次对消息排队以进行传递。 因此,设备应用中的消息处理逻辑必须是幂等的,这样,多次接收相同的消息才会生成相同的结果。

若要获取有关云到设备消息生命周期以及 IoT 中心如何处理云到设备消息的详细信息,请参阅从 IoT 中心发送云到设备的消息

注意

如果使用 HTTPS(而不使用 MQTT 或 AMQP)作为传输,则 DeviceClient 实例不会频繁检查 IoT 中心发来的消息(频率最低为每 25 分钟一次)。 有关 MQTT、AMQP 和 HTTPS 支持之间的差异的详细信息,请参阅云到设备通信指南选择通信协议

获取 IoT 中心连接字符串

本文中,你将创建一个后端服务,用于通过 IoT 中心发送云到设备消息。 若要发送云到设备消息,服务需要服务连接权限。 默认情况下,每个 IoT 中心都使用名为“服务”的共享访问策略创建,该策略会授予此权限。

若要获取 service策略的 IoT 中心连接字符串,请执行以下步骤:

  1. Azure 门户中,选择“资源组”。 选择中心所在的资源组,然后从资源列表中选择中心。

  2. 在 IoT 中心的左侧窗格上,选择“共享访问策略”。

  3. 在策略列表中,选择“service”策略。

  4. 复制“主连接字符串”并保存该值。

Screenshot that shows how to retrieve the connection string from your IoT Hub in the Azure portal.

有关 IoT 中心共享访问策略和权限的详细信息,请参阅访问控制和权限

发送云到设备的消息

在本部分中,会创建 Java 控制台应用,用于向模拟设备应用发送“云到设备”消息。 需要设备的设备 ID 和 IoT 中心连接字符串。

  1. 在命令提示符处使用以下命令,创建名为 send-c2d-messages 的 Maven 项目。 请注意,此命令是一条很长的命令:

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

  3. 使用文本编辑器,打开 send-c2d-messages 文件夹中的 pom.xml 文件,并在 dependencies 节点中添加以下依赖项。 这样即可使用应用程序中的 iothub-java-service-client 包来与 IoT 中心服务通信:

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

    注意

    可以使用 Maven 搜索检查是否有最新版本的 iot-service-client

  4. 保存并关闭 pom.xml 文件。

  5. 使用文本编辑器打开 send-c2d-messages\src\main\java\com\mycompany\app\App.java 文件。

  6. 在该文件中添加以下 import 语句:

    import com.microsoft.azure.sdk.iot.service.*;
    import java.io.IOException;
    import java.net.URISyntaxException;
    
  7. 将以下类级变量添加到 App 类,并将 {yourhubconnectionstring} 和 {yourdeviceid} 替换为前面记下的值 :

    private static final String connectionString = "{yourhubconnectionstring}";
    private static final String deviceId = "{yourdeviceid}";
    private static final IotHubServiceClientProtocol protocol =    
        IotHubServiceClientProtocol.AMQPS;
    
  8. main方法替换为以下代码。 此代码用于连接到 IoT 中心,将消息发送到设备,然后等待设备已接收并处理消息的通知:

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

    注意

    为简单起见,本文不实现重试策略。 在生产代码中,应该按暂时性故障处理一文中所述实施重试策略(例如指数退避)。

  9. 若要使用 Maven 生成 simulated-device 应用,请在 simulated-device 文件夹中的命令提示符下执行以下命令:

    mvn clean package -DskipTests
    

运行应用程序

现在,已准备就绪,可以运行应用程序了。

  1. 在 simulated-device 文件夹的命令提示符处,运行以下命令以发送遥测数据至 IoT 中心并侦听中心发出的云到设备消息:

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

    Run the simulated device app

  2. 在 send-c2d-messages 文件夹的命令提示符处,运行以下命令以发送云到设备的消息并等待反馈确认:

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

    Run the command to send the cloud-to-device message

后续步骤

本文已介绍了如何发送和接收云到设备消息。