

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

# 演示使用 Amazon IoT 设备客户端订阅消息
<a name="iot-dc-testconn-subscribe"></a>

在本节中，您将演示两种类型的消息订阅：
+ 单独订阅主题
+ 通配符主题订阅

为这些练习创建的策略中的策略语句授予 Raspberry Pi 执行这些操作的权限：
+ 

**`iot:Receive`**  
授予 Amazon IoT 设备客户端接收与`Resource`对象中命名主题相匹配的 MQTT 主题的权限。

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Receive"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/subtopic"
        ]
      }
  ```
+ 

**`iot:Subscribe`**  
向 Amazon IoT 设备客户端授予订阅与`Resource`对象中命名的过滤器相匹配的 MQTT 主题过滤器的权限。

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Subscribe"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/subtopic"
        ]
      }
  ```

## 订阅单个 MQTT 消息主题
<a name="iot-dc-testconn-subscribe-simple-topic"></a>

此过程演示 Amazon IoT 设备客户端如何订阅和记录 MQTT 消息。

在连接到 Raspberry Pi 的本地主机上的终端窗口中，列出 **\~/dc-configs/dc-pubsub-custom-config.json** 的内容或者在文本编辑器中打开该文件查看内容。定位 `samples` 对象，应如下所示。

```
  "samples": {
    "pub-sub": {
      "enabled": true,
      "publish-topic": "test/dc/pubtopic",
      "publish-file": "~/messages/sample-ws-message.json",
      "subscribe-topic": "test/dc/subtopic",
      "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
```

注意 `subscribe-topic` 值是 Amazon IoT Device Client 将在运行时订阅的 MQTT 主题。 Amazon IoT 设备客户端将其从此订阅中收到的消息负载写入`subscribe-file`值中命名的文件。

**从 Amazon IoT 设备客户端订阅 MQTT 消息主题**

1. 在执行此过程时，确保终端窗口和窗口都有 MQTT 测试客户端可见。此外，请确保 **MQTT 测试客户端**仍订阅为**\#**主题筛选条件。如果没有订阅，请再次订阅**\#**筛选条件主题。

1. 在终端窗口中，输入这些命令以使用中创建的配置文件运行 Amazon IoT 设备客户端[创建配置文件](iot-dc-install-configure.md#iot-dc-install-dc-configure-step1)。

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-custom-config.json
   ```

   在终端窗口中， Amazon IoT 设备客户端显示信息消息以及运行时出现的任何错误。

   如果终端窗口中未显示错误，请在 Amazon IoT 控制台继续。

1. 在 Amazon IoT 控制台的 **MQTT 测试客户端**中，选择**发布到主题**选项卡。

1. 在 **主题名称**中，输入 **test/dc/subtopic**。

1. 在**消息有效载荷**中，查看消息内容。

1. 选择 **Publish**（发布）发布 MQTT 消息。

1. 在终端窗口中，注意从 Amazon IoT 设备客户端*收到的如下所示的消息*条目。

   ```
   2021-11-10T16:02:20.890Z [DEBUG] {samples/PubSubFeature.cpp}: Message received on subscribe topic, size: 45 bytes
   ```

1. 看到显示*已收到消息的消息*条目后，输入 **^C** (Ctrl-C) 停止 Amazon IoT 设备客户端。

1. 输入此命令可查看消息日志文件的末尾并查看您从 **MQTT 测试客户端**发布的信息

   ```
   tail ~/.aws-iot-device-client/log/pubsub_rx_msgs.log
   ```

通过查看日志文件中的消息，您已经演示了 Amazon IoT Device Client 收到了您从 MQTT 测试客户端发布的消息。

## 使用通配符订阅多个 MQTT 消息主题
<a name="iot-dc-testconn-subscribe-wild-topic"></a>

这些过程演示了 Amazon IoT 设备客户端如何使用通配符订阅和记录 MQTT 消息。要做到这一点，您将：

1. 更新 Amazon IoT 设备客户端用于订阅 MQTT 主题的主题筛选器。

1. 更新设备使用的策略允许新订阅。

1. 运行 Amazon IoT 设备客户端并从 MQTT 测试控制台发布消息。

**使用通配符 MQTT 主题筛选条件创建配置文件订阅多个 MQTT 消息主题**

1. 在连接到 Raspberry Pi 的本地主机上的终端窗口中，打开 **\~/dc-configs/dc-pubsub-custom-config.json** 进行编辑并定位 `samples` 对象。

1. 在文本编辑器中，定位 `samples` 对象并更新 `subscribe-topic` 值如下所示。

   ```
     "samples": {
       "pub-sub": {
         "enabled": true,
         "publish-topic": "test/dc/pubtopic",
         "publish-file": "~/messages/sample-ws-message.json",
         "subscribe-topic": "test/dc/#",
         "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
   ```

   新 `subscribe-topic`值是 [MQTT 主题筛选条件](topics.md#topicfilters)，其末尾带有 MQTT 通配符。这描述了以 `test/dc/`开始的所有 MQTT 主题的订阅。 Amazon IoT 设备客户端将其从此订阅中收到的消息负载写入中`subscribe-file`名为的文件。

1. 将修改后的配置文件另存为 **\~/dc-configs/dc-pubsub-wild-config.json**，然后退出编辑器。

**修改 Raspberry Pi 使用的策略允许订阅和接收多个 MQTT 消息主题**

1. 在连接到 Raspberry Pi 的本地主机上的终端窗口中，在您最喜欢的文本编辑器中打开 **\~/policies/pubsub\_test\_thing\_policy.json** 进行编辑，然后定位 `iot::Subscribe` 和 `iot::Receive` 文件中的策略语句。

1. 在`iot::Subscribe`策略语句中更新 Resource 对象中的字符串用 `*`替换 `subtopic`，如下所示。

   ```
       {
         "Effect": "Allow",
         "Action": [
           "iot:Subscribe"
         ],
         "Resource": [
           "arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/*"
         ]
       }
   ```
**注意**  
[MQTT 主题筛选条件通配符](topics.md#topicfilters) 是 `+`（加号）和 `#`（磅符号）。结尾带有 `#` 的订阅请求订阅以字符前面的字符串开头的 `#` 所有主题（例如，在本使用案例中为 `test/dc/`）。  
但是，授权此订阅的策略语句中的资源值必须在主题筛选条件ARN中使用 `*`（星号）代替 `#`（磅号）。这是因为策略处理器使用的通配符不同于 MQTT 使用的通配符。  
有关在策略中为主题和主题筛选条件使用通配符的详细信息，请参阅 [在 MQTT 和策略中使用通配符 Amazon IoT Core](pub-sub-policy.md#pub-sub-policy-cert)。

1. 在 `iot::Receive`策略语句中更新 Resource 对象中的字符串用 `subtopic`替换 `*`，如下所示。

   ```
       {
         "Effect": "Allow",
         "Action": [
           "iot:Receive"
         ],
         "Resource": [
           "arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/*"
         ]
       }
   ```

1. 将更新后的策略文档另存为 **\~/policies/pubsub\_wild\_test\_thing\_policy.json**，然后退出编辑器。

1. 输入此命令可更新本教程的策略使用新的资源定义。

   ```
   aws iot create-policy-version \
   --set-as-default \
   --policy-name "PubSubTestThingPolicy" \
   --policy-document "file://~/policies/pubsub_wild_test_thing_policy.json"
   ```

   如果命令成功，将返回类似于此类的响应。请注意，`policyVersionId` 现在是 `2`，表示这是此策略的第二个版本。

   如果成功更新策略，可以继续下一个过程。

   ```
   {
       "policyArn": "arn:aws:iot:us-west-2:57EXAMPLE833:policy/PubSubTestThingPolicy",
       "policyDocument": "{\n  \"Version\": \"2012-10-17\",		 	 	 \n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Connect\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:client/PubSubTestThing\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Publish\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/pubtopic\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Subscribe\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:topicfilter/test/dc/*\"\n      ]\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"iot:Receive\"\n      ],\n      \"Resource\": [\n        \"arn:aws:iot:us-west-2:57EXAMPLE833:topic/test/dc/*\"\n      ]\n    }\n  ]\n}\n",
       "policyVersionId": "2",
       "isDefaultVersion": true
   }
   ```

   如果您收到有太多策略版本无法保存新版本的错误，请输入此命令列出策略的当前版本。查看此命令返回的列表查找可以删除的策略版本。

   ```
   aws iot list-policy-versions --policy-name "PubSubTestThingPolicy"
   ```

   输入此命令删除不再需要的版本。请注意，您无法删除原定设置策略版本。原定设置策略版本为具有 `true` 的 `isDefaultVersion` 值。

   ```
   aws iot delete-policy-version \
   --policy-name "PubSubTestThingPolicy" \
   --policy-version-id {{policyId}}
   ```

   删除策略版本后，请重试此步骤。

有了更新的配置文件和策略，您就可以通过 Amazon IoT 设备客户端演示通配符订阅了。

**演示 Amazon IoT 设备客户端如何订阅和接收多个 MQTT 消息主题**

1. 在 **MQTT 测试客户端**，检查订阅。如果已在 **\#** 主题筛选条件中订阅了 **MQTT 测试客户端**，请继续执行下一步。如果没有订阅，在 **MQTT 测试客户端**，在**订阅主题**选项卡的**主题筛选条件**中，输入 **\#**（井号），然后选择**订阅**以进行订阅。

1. 在连接到 Raspberry Pi 的本地主机上的终端窗口中，输入这些命令启动 Amazon IoT Device Client。

   ```
   cd ~/aws-iot-device-client/build
   ./aws-iot-device-client --config-file ~/dc-configs/dc-pubsub-wild-config.json
   ```

1. 在本地主机的终端窗口中观看 Amazon IoT 设备客户端输出时，返回 **MQTT 测试客户端**。在**发布主题**选项卡中，**主题名称**，输入 **test/dc/subtopic**，然后选择**发布**。

1. 在终端窗口中，通过查找以下消息确认已收到消息，例如：

   ```
   2021-11-10T16:34:20.101Z [DEBUG] {samples/PubSubFeature.cpp}: Message received on subscribe topic, size: 76 bytes
   ```

1. 在本地主机的终端窗口中观看 Amazon IoT 设备客户端输出时，返回 **MQTT 测试客户端**。在**发布主题**选项卡中，**主题名称**，输入 **test/dc/subtopic2**，然后选择**发布**。

1. 在终端窗口中，通过查找以下消息确认已收到消息，例如：

   ```
   2021-11-10T16:34:32.078Z [DEBUG] {samples/PubSubFeature.cpp}: Message received on subscribe topic, size: 77 bytes
   ```

1. 看到确认收到两条消息的消息后，输入 **^C** (Ctrl-C) 停止 Amazon IoT 设备客户端。

1. 输入此命令可查看消息日志文件的末尾并查看您从 **MQTT 测试客户端**发布的信息

   ```
   tail -n 20 ~/.aws-iot-device-client/log/pubsub_rx_msgs.log
   ```
**注意**  
该日志文件仅包含消息有效载荷。消息主题不会记录在收到的消息日志文件中。  
您还可能在收到的日志中看到 Amazon IoT 设备客户端发布的消息。这是因为通配符主题筛选条件包含该消息主题，有时候，在发布的消息发送给订阅者之前，消息代理可以处理订阅请求。

日志文件中的条目表明已收到消息。您可以使用其他主题名称重复此过程。主题名称以 `test/dc/` 开头的所有消息应该接收并记录。主题名称以任何其他文本开头的消息将被忽略。

演示 Amazon IoT 设备客户端如何发布和订阅 MQTT 消息后，请继续。[教程：使用 Amazon IoT 设备客户端演示远程操作（作业）](iot-dc-runjobs.md)