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

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

本文将向您介绍如何操作:

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

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

  • 请求来自您的解决方案后端的传递确认(反馈),用于从 IoT 中心发送到设备的消息。

注释

本文中所述的功能仅在 IoT 中心的标准层中可用。 有关基本层和标准/免费 IoT 中心层的详细信息,请参阅 为解决方案选择正确的 IoT 中心层和大小

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

注释

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

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

先决条件

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

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

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

  2. 将以下 MessageCallback 类添加为 App 类中的嵌套类。 当设备从 IoT 中心收到消息时,将调用 执行 方法。 在此示例中,设备始终通知 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. 修改 方法以创建 AppMessageCallback 实例,并在打开客户端之前调用 setMessageCallback 方法,如下所示:

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

    mvn clean package -DskipTests
    

execute类中的AppMessageCallback方法返回 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. 复制“主连接字符串”并保存该值

显示如何在 Azure 门户中从 IoT 中心检索连接字符串的屏幕截图。

有关 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 文件,并将以下依赖项添加到 依赖项 节点。 通过添加依赖项,可以在应用程序中使用 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 文件夹中的命令提示符处执行以下命令:

    mvn clean package -DskipTests
    

运行应用程序

现在可以运行应用程序了。

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

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

    运行模拟设备应用

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

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

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

后续步骤

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