配置远程设备和使用 IoT 代理 - Amazon IoT Core
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

配置远程设备和使用 IoT 代理

IoT 代理用于接收包含客户端访问令牌的 MQTT 消息,并在远程设备上启动本地代理。如果希望安全隧道使用 MQTT 传送客户端访问令牌,则必须在远程设备上安装并运行 IoT 代理。IoT 代理必须订阅以下保留的 IoT MQTT 主题:

注意

如果要通过订阅保留 MQTT 主题之外的方法将目标客户端访问令牌传送到远程设备,您可能需要目标客户端访问令牌 (CAT) 侦听器和本地代理。CAT 侦听器必须使用您选择的客户端访问令牌传送机制,并且能够在目标模式下启动本地代理。

IoT 代理代码段

IoT 代理必须订阅以下保留 IoT MQTT 主题,这样才能接收 MQTT 消息并启动本地代理:

$aws/things/thing-name/tunnels/notify

thing-name与远程设备关联 Amazon IoT 的事物的名称在哪里。

以下是 MQTT 消息负载示例:

{ "clientAccessToken": "destination-client-access-token", "clientMode": "destination", "region": "aws-region", "services": ["destination-service"] }

当您收到 MQTT 消息后,IoT 代理必须在远程设备上使用适当参数启动本地代理。

以下 Java 代码演示了如何使用Amazon IoT 设备 SDKProcessBuilderJava 库来构建用于安全隧道的简单物联网代理。

// Find the IoT device endpoint for your Amazon Web Services 账户 final String endpoint = iotClient.describeEndpoint(new DescribeEndpointRequest().withEndpointType("iot:Data-ATS")).getEndpointAddress(); // Instantiate the IoT Agent with your Amazon credentials final String thingName = "RemoteDeviceA"; final String tunnelNotificationTopic = String.format("$aws/things/%s/tunnels/notify", thingName); final AWSIotMqttClient mqttClient = new AWSIotMqttClient(endpoint, thingName, "your_aws_access_key", "your_aws_secret_key"); try { mqttClient.connect(); final TunnelNotificationListener listener = new TunnelNotificationListener(tunnelNotificationTopic); mqttClient.subscribe(listener, true); } finally { mqttClient.disconnect(); } private static class TunnelNotificationListener extends AWSIotTopic { public TunnelNotificationListener(String topic) { super(topic); } @Override public void onMessage(AWSIotMessage message) { try { // Deserialize the MQTT message final JSONObject json = new JSONObject(message.getStringPayload()); final String accessToken = json.getString("clientAccessToken"); final String region = json.getString("region"); final String clientMode = json.getString("clientMode"); if (!clientMode.equals("destination")) { throw new RuntimeException("Client mode " + clientMode + " in the MQTT message is not expected"); } final JSONArray servicesArray = json.getJSONArray("services"); if (servicesArray.length() > 1) { throw new RuntimeException("Services in the MQTT message has more than 1 service"); } final String service = servicesArray.get(0).toString(); if (!service.equals("SSH")) { throw new RuntimeException("Service " + service + " is not supported"); } // Start the destination local proxy in a separate process to connect to the SSH Daemon listening port 22 final ProcessBuilder pb = new ProcessBuilder("localproxy", "-t", accessToken, "-r", region, "-d", "localhost:22"); pb.start(); } catch (Exception e) { log.error("Failed to start the local proxy", e); } } }