本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
IoT 代理用于接收包含客户端访问令牌的 MQTT 消息,并在远程设备上启动本地代理。如果希望安全隧道使用 MQTT 传送客户端访问令牌,则必须在远程设备上安装并运行 IoT 代理。IoT 代理必须订阅以下保留的 IoT MQTT 主题:
注意
如果要通过订阅保留 MQTT 主题之外的方法将目标客户端访问令牌传送到远程设备,您可能需要目标客户端访问令牌 (CAT) 侦听器和本地代理。CAT 侦听器必须使用您选择的客户端访问令牌传送机制,并且能够在目标模式下启动本地代理。
IoT 代理代码段
IoT 代理必须订阅以下保留 IoT MQTT 主题,这样才能接收 MQTT 消息并启动本地代理:
$aws/things/
thing-name
/tunnels/notify
thing-name
与远程设备关联 AWS IoT 的事物的名称在哪里。
以下是 MQTT 消息负载示例:
{
"clientAccessToken": "destination-client-access-token
",
"clientMode": "destination",
"region": "aws-region
",
"services": ["destination-service
"]
}
当您收到 MQTT 消息后,IoT 代理必须在远程设备上使用适当参数启动本地代理。
以下 Java 代码演示了如何使用AWS IoT 设备 SDK
// Find the IoT device endpoint for your AWS 账户
final String endpoint = iotClient.describeEndpoint(new DescribeEndpointRequest().withEndpointType("iot:Data-ATS")).getEndpointAddress();
// Instantiate the IoT Agent with your AWS 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);
}
}
}