

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

# 教程：演示与 Amazon IoT 设备客户端的 MQTT 消息通信
使用 MQTT 与 Device Client 通信

本教程演示 Amazon IoT 设备客户端如何订阅和发布物联网解决方案中常用的 MQTT 消息。

**要开始本教程：**
+ 将本地主机和 Raspberry Pi 配置为在[上一节](iot-dc-install-dc.md)使用。

  如果您在安装 Amazon IoT 设备客户端后保存了 microSD 卡映像，则可以将带有该图像的 microSD 卡与 Raspberry Pi 一起使用。
+ 如果您之前运行过此演示，[第 2 步：使用 Amazon IoT 设备客户端 Amazon Web Services 账户 在构建演示之后清理你的](iot-dc-cleanup.md#iot-dc-cleanup-cloud)请查看删除您在之前运行中创建的所有 Amazon IoT 资源，以避免出现重复的资源错误。

完成本教程需要大约 45 分钟。

**完成本主题后：**
+ 您将演示物联网设备订阅 MQTT 消息 Amazon IoT 并向其发布 MQTT 消息的不同方式。 Amazon IoT

**所需的设备：**
+ [上一节](iot-dc-install-dc.md)中您的本地开发和测试环境
+ [上一节](iot-dc-install-dc.md)中您使用 的Raspberry Pi
+ [上一节](iot-dc-install-dc.md)中您使用的 Raspberry Pi microSD 记忆卡

**Topics**
+ [

# 准备 Raspberry Pi 来演示 MQTT 消息通信
](iot-dc-testconn-provision.md)
+ [

# 演示使用 Amazon IoT 设备客户端发布消息
](iot-dc-testconn-publish.md)
+ [

# 演示使用 Amazon IoT 设备客户端订阅消息
](iot-dc-testconn-subscribe.md)

# 准备 Raspberry Pi 来演示 MQTT 消息通信
为 MQTT 准备 Raspberry Pi

此过程在 Raspberry Pi 中 Amazon IoT 和中创建资源，以演示使用 Amazon IoT 设备客户端进行 MQTT 消息通信。

**Topics**
+ [

## 创建证书文件演示 MQTT 通信
](#iot-dc-testconn-provision-certs)
+ [

## 预调配您的设备演示 MQTT 通信
](#iot-dc-testconn-provision-aws)
+ [

## 配置 Amazon IoT 设备客户端配置文件和 MQTT 测试客户端，演示 MQTT 通信
](#iot-dc-testconn-provision-dc-config)

## 创建证书文件演示 MQTT 通信
创建证书文件

此过程为此演示创建设备证书文件。

**要为 Raspberry Pi 创建和下载设备证书文件**



1. 在本地主机的终端窗口中，输入以下命令为您的设备创建设备证书文件。

   ```
   mkdir ~/certs/pubsub
   aws iot create-keys-and-certificate \
   --set-as-active \
   --certificate-pem-outfile "~/certs/pubsub/device.pem.crt" \
   --public-key-outfile "~/certs/pubsub/public.pem.key" \
   --private-key-outfile "~/certs/pubsub/private.pem.key"
   ```

   此命令会返回类似以下内容的响应。保存 `certificateArn`值供稍后使用。

   ```
   {
   "certificateArn": "arn:aws:iot:us-west-2:57EXAMPLE833:cert/76e7e4edb3e52f52334be2f387a06145b2aa4c7fcd810f3aea2d92abc227d269",
   "certificateId": "76e7e4edb3e52f5233EXAMPLE7a06145b2aa4c7fcd810f3aea2d92abc227d269",
   "certificatePem": "-----BEGIN CERTIFICATE-----\nMIIDWTCCAkGgAwIBAgI_SHORTENED_FOR_EXAMPLE_Lgn4jfgtS\n-----END CERTIFICATE-----\n",
   "keyPair": {
       "PublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BA_SHORTENED_FOR_EXAMPLE_ImwIDAQAB\n-----END PUBLIC KEY-----\n",
       "PrivateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQE_SHORTENED_FOR_EXAMPLE_T9RoDiukY\n-----END RSA PRIVATE KEY-----\n"
   }
   }
   ```

1. 输入以下命令设置证书目录及其文件的权限。

   ```
   chmod 700 ~/certs/pubsub
   chmod 644 ~/certs/pubsub/*
   chmod 600 ~/certs/pubsub/private.pem.key
   ```

1. 运行此命令可查看证书目录和文件的权限。

   ```
   ls -l ~/certs/pubsub
   ```

   命令的输出应与您在此处看到的内容相同，但文件日期和时间会有所不同。

   ```
   -rw-r--r-- 1 pi pi 1220 Oct 28 13:02 device.pem.crt
   -rw------- 1 pi pi 1675 Oct 28 13:02 private.pem.key
   -rw-r--r-- 1 pi pi  451 Oct 28 13:02 public.pem.key
   ```

1. 输入这些命令创建日志文件的目录。

   ```
   mkdir ~/.aws-iot-device-client
   mkdir ~/.aws-iot-device-client/log
   chmod 745 ~/.aws-iot-device-client/log
   echo " " > ~/.aws-iot-device-client/log/aws-iot-device-client.log
   echo " " > ~/.aws-iot-device-client/log/pubsub_rx_msgs.log
   chmod 600 ~/.aws-iot-device-client/log/*
   ```

## 预调配您的设备演示 MQTT 通信
为 MQTT 预调配设备

本节创建了在中配置 Raspberry Pi 的 Amazon IoT 资源 Amazon IoT。

**在 Amazon IoT中预置您的设备：**

1. 在本地主机的终端窗口中，输入以下命令获取您的 Amazon Web Services 账户设备数据端点的地址。

   ```
   aws iot describe-endpoint --endpoint-type IoT:Data-ATS
   ```

   自从您为上一教程运行此命令以来，端点值一直没有更改。再次在此处运行命令是为了方便地查找数据端点值并将其粘贴到本教程中使用的配置文件中。

   上面步骤的命令会返回类似以下内容的响应。记录 `endpointAddress`值以供将来使用。

   ```
   {
   "endpointAddress": "a3qjEXAMPLEffp-ats.iot.us-west-2.amazonaws.com"
   }
   ```

1. 输入此命令为您的 Raspberry Pi 创建新 Amazon IoT 事物资源。

   ```
   aws iot create-thing --thing-name "PubSubTestThing"
   ```

   由于 Amazon IoT 事物资源是您的设备在云中的*虚拟*表示，因此我们可以创建多个事物资源 Amazon IoT 以用于不同的目的。它们都可以由同一物理 IoT 设备使用来表示设备的不同方面。

   这些教程一次只能使用一个事物资源来表示 Raspberry Pi。这样，在这些教程中，它们代表了不同的演示，因此在为演示创建 Amazon IoT 资源之后，您可以返回并使用专门为每个演示创建的资源重复演示。

   如果您的 Amazon IoT 事物资源已创建，则该命令会返回类似这样的响应。

   ```
   {
   "thingName": "PubSubTestThing",
   "thingArn": "arn:aws:iot:us-west-2:57EXAMPLE833:thing/PubSubTestThing",
   "thingId": "8ea78707-32c3-4f8a-9232-14bEXAMPLEfd"
   }
   ```

1. 在终端窗口中：

   1. 打开文本编辑器，例如 `nano`。

   1. 复制此 JSON 文档并将其粘贴到打开的文本编辑器中。  
****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Connect"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:client/PubSubTestThing"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Publish"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/test/dc/pubtopic"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Subscribe"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topicfilter/test/dc/subtopic"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Receive"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-west-2:123456789012:topic/test/dc/subtopic"
                  ]
              }
          ]
      }
      ```

   1. 在编辑器中，在政策文档的每个`Resource`部分中，*us-west-2:57EXAMPLE833*用您 Amazon Web Services 区域的、冒号字符 (:) 和您的 12 位 Amazon Web Services 账户 数字替换。

   1. 将文本编辑器中的文件保存为 **\$1/policies/pubsub\$1test\$1thing\$1policy.json**。

1. 运行此命令使用前面步骤中的策略文档来创建 Amazon IoT 策略。

   ```
   aws iot create-policy \
   --policy-name "PubSubTestThingPolicy" \
   --policy-document "file://~/policies/pubsub_test_thing_policy.json"
   ```

   如果创建策略，该命令将返回类似此类的响应。

   ```
   {
                                       "policyName": "PubSubTestThingPolicy",
                                       "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/subtopic\"\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": "1"
                                       }
   ```

1. 运行此命令将策略附加到设备证书。将 `certificateArn`替换为您之前在本部分保存的 `certificateArn`值。

   ```
   aws iot attach-policy \
   --policy-name "PubSubTestThingPolicy" \
   --target "certificateArn"
   ```

   如果成功，该命令不返回任何内容。

1. 运行此命令将设备证书附加到 Amazon IoT 事物资源。将 `certificateArn`替换为您之前在本部分保存的 `certificateArn`值。

   ```
   aws iot attach-thing-principal \
   --thing-name "PubSubTestThing" \
   --principal "certificateArn"
   ```

   如果成功，该命令不返回任何内容。

在中成功配置设备后 Amazon IoT，就可以继续操作了[配置 Amazon IoT 设备客户端配置文件和 MQTT 测试客户端，演示 MQTT 通信](#iot-dc-testconn-provision-dc-config)。

## 配置 Amazon IoT 设备客户端配置文件和 MQTT 测试客户端，演示 MQTT 通信
配置 Device Client 配置文件和 MQTT 客户端

此过程创建一个配置文件来测试 Amazon IoT 设备客户端。

**创建用于测试 Amazon IoT 设备客户端的配置文件**

1. 在连接到 Raspberry Pi 的本地主机的终端窗口中：

   1. 打开文本编辑器，例如 `nano`。

   1. 复制此 JSON 文档并将其粘贴到打开的文本编辑器中。

      ```
      {
        "endpoint": "a3qEXAMPLEaffp-ats.iot.us-west-2.amazonaws.com",
        "cert": "~/certs/pubsub/device.pem.crt",
        "key": "~/certs/pubsub/private.pem.key",
        "root-ca": "~/certs/AmazonRootCA1.pem",
        "thing-name": "PubSubTestThing",
        "logging": {
          "enable-sdk-logging": true,
          "level": "DEBUG",
          "type": "STDOUT",
          "file": ""
        },
        "jobs": {
          "enabled": false,
          "handler-directory": ""
        },
        "tunneling": {
          "enabled": false
        },
        "device-defender": {
          "enabled": false,
          "interval": 300
        },
        "fleet-provisioning": {
          "enabled": false,
          "template-name": "",
          "template-parameters": "",
          "csr-file": "",
          "device-key": ""
        },
        "samples": {
          "pub-sub": {
            "enabled": true,
            "publish-topic": "test/dc/pubtopic",
            "publish-file": "",
            "subscribe-topic": "test/dc/subtopic",
            "subscribe-file": "~/.aws-iot-device-client/log/pubsub_rx_msgs.log"
          }
        },
        "config-shadow": {
          "enabled": false
        },
        "sample-shadow": {
          "enabled": false,
          "shadow-name": "",
          "shadow-input-file": "",
          "shadow-output-file": ""
        }
      }
      ```

   1. 将该*endpoint*值替换为您在中找到的设备数据端点[在中配置您的设备 Amazon IoT Core](iot-dc-install-provision.md#iot-dc-install-dc-provision)。 Amazon Web Services 账户 

   1. 将文本编辑器中的文件保存为 **\$1/dc-configs/dc-pubsub-config.json**。

   1. 运行这个命令在新文件上设置权限

      ```
      chmod 644 ~/dc-configs/dc-pubsub-config.json
      ```

1. 准备 **MQTT 测试客户端**订阅所有 MQTT 消息：

   1. 在本地主机上，在[Amazon IoT 控制台](https://console.amazonaws.cn//iot/home#/test)，选择**MQTT 测试客户端**。

   1. 在**订阅主题**选项卡上，在**主题筛选条件**中，输入 **\$1**（单个井号），然后选择**订阅**。

   1. 在**订阅**标签下，确认您看见 **\$1**（单独英镑符号）。

   继续此教程时，让窗口的 **MQTT 测试客户端** 保持打开。

保存文件并配置 **MQTT 测试客户端**后，您便可以继续 [演示使用 Amazon IoT 设备客户端发布消息](iot-dc-testconn-publish.md)。

# 演示使用 Amazon IoT 设备客户端发布消息
使用 IoT Device Client 发布消息

本节中的过程演示 Amazon IoT 设备客户端如何发送默认和自定义 MQTT 消息。

在上一步中为这些练习创建的策略中的以下策略声明授予 Raspberry Pi 执行以下操作的权限：
+ 

**`iot:Connect`**  
让名`PubSubTestThing`为的客户端（运行 Amazon IoT 设备客户端的 Raspberry Pi）进行连接。

  ```
      {
        "Effect": "Allow",
        "Action": [
          "iot:Connect"
        ],
        "Resource": [
          "arn:aws:iot:us-west-2:57EXAMPLE833:client/PubSubTestThing"
        ]
      }
  ```
+ 

**`iot:Publish`**  
授予 Raspberry Pi 用 `test/dc/pubtopic` MQTT 主题发布消息的全效。

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

  `iot:Publish` 操作提供发布到资源数组中列出的 MQTT 主题权限。那些消息的*内容*不受策略声明的控制。

## 使用 Amazon IoT 设备客户端发布默认消息
发布默认 MQTT 消息

此过程运行 Amazon IoT 设备客户端，以便它发布一条默认 MQTT 消息，MQT **T 测试客户端**会收到并显示该消息。

**从 Amazon IoT 设备客户端发送默认 MQTT 消息**

1. 执行此过程时，请确保连接到 Raspberry Pi 的本地主机上的终端窗口和使用 **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-config.json
   ```

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

   如果终端窗口中没有显示错误，请查看 **MQTT 测试客户端**。

1. 在 **MQTT 测试客户端**的**订阅**窗口中，查看发送到 `test/dc/pubtopic` 消息主题的 *Hello World\$1* 消息。

1. 如果 Amazon IoT 设备客户端没有显示任何错误并且你看到 *Hello World！* 发送到 **MQTT 测试客户端**中的`test/dc/pubtopic`消息时，您已演示连接成功。

1. 在终端窗口中，输入 **^C** (Ctrl-C) 以停止 Amazon IoT 设备客户端。

在您演示 Amazon IoT 设备客户端发布了默认 MQTT 消息之后，您可以继续。[使用 Amazon IoT 设备客户端发布自定义消息](#iot-dc-testconn-publish-custom)

## 使用 Amazon IoT 设备客户端发布自定义消息
发布自定义 MQTT 消息

本节中的步骤创建一条自定义 MQTT 消息，然后运行 Amazon IoT Device Client，以便将自定义 MQTT 消息发布一次，以便 **MQTT 测试客户端**接收和显示。

### 为 Amazon IoT 设备客户端创建自定义 MQTT 消息


在连接到 Raspberry Pi 的本地主机上的终端窗口中执行以下步骤。

**创建自定义消息供 Amazon IoT 设备客户端发布**

1. 在终端窗口中，打开文本编辑器，例如 `nano`。

1. 在文本编辑器中，复制并粘贴以下 JSON 文档。这将是 Amazon IoT 设备客户端发布的 MQTT 消息有效负载。

   ```
   {
     "temperature": 28,
     "humidity": 80,
     "barometer": 1013,
     "wind": {
       "velocity": 22,
       "bearing": 255
     }
   }
   ```

1. 将文本编辑器的内容另存为 **\$1/messages/sample-ws-message.json**。

1. 输入以下命令设置刚才创建的消息文件的权限。

   ```
   chmod 600 ~/messages/*
   ```

**为 Amazon IoT 设备客户端创建用于发送自定义消息的配置文件**

1. 在终端窗口中，在文本编辑器（例如）中`nano`，打开现有的 Amazon IoT 设备客户端配置文件：**\$1/dc-configs/dc-pubsub-config.json**。

1. 编辑 `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"
   ```

1. 将文本编辑器的内容另存为 **\$1/dc-configs/dc-pubsub-custom-config.json**。

1. 运行这个命令在新文件上设置权限

   ```
   chmod 644 ~/dc-configs/dc-pubsub-custom-config.json
   ```

### 使用 Amazon IoT 设备客户端发布自定义 MQTT 消息


此更改仅影响 MQTT 消息有效载荷的*内容*，因此当前策略将继续工作。但是，如果*MQTT 主题*（由 `~/dc-configs/dc-pubsub-custom-config.json` 红的 `publish-topic` 值定义) 已更改，还需要修改策略语句 `iot::Publish`，允许 Raspberry Pi 发布到新的 MQTT 主题。

**从 Amazon IoT 设备客户端发送 MQTT 消息**

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

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

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

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

   如果终端窗口中没有显示错误，请查看 MQTT 测试客户端。

1. 在 **MQTT 测试客户端**中，在**订阅窗口**中，请参阅发送到 `test/dc/pubtopic` 消息主题的自定义消息有效载荷。

1. 如果 Amazon IoT 设备客户端未显示任何错误，并且您看到在 **MQTT 测试客户端**中发布到`test/dc/pubtopic`消息的自定义消息负载，则表示您已成功发布自定义消息。

1. 在终端窗口中，输入 **^C** (Ctrl-C) 以停止 Amazon IoT 设备客户端。

在您证明 Amazon IoT 设备客户端发布了自定义消息负载之后，您可以继续[演示使用 Amazon IoT 设备客户端订阅消息](iot-dc-testconn-subscribe.md)。

# 演示使用 Amazon IoT 设备客户端订阅消息
使用 IoT Device Client 订阅消息

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

为这些练习创建的策略中的策略语句授予 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 消息主题


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

在连接到 Raspberry Pi 的本地主机上的终端窗口中，列出 **\$1/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**主题筛选条件。如果没有订阅，请再次订阅**\$1**筛选条件主题。

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 消息主题


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

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

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

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

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

1. 在连接到 Raspberry Pi 的本地主机上的终端窗口中，打开 **\$1/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. 将修改后的配置文件另存为 **\$1/dc-configs/dc-pubsub-wild-config.json**，然后退出编辑器。

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

1. 在连接到 Raspberry Pi 的本地主机上的终端窗口中，在您最喜欢的文本编辑器中打开 **\$1/policies/pubsub\$1test\$1thing\$1policy.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. 将更新后的策略文档另存为 **\$1/policies/pubsub\$1wild\$1test\$1thing\$1policy.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 测试客户端**，检查订阅。如果已在 **\$1** 主题筛选条件中订阅了 **MQTT 测试客户端**，请继续执行下一步。如果没有订阅，在 **MQTT 测试客户端**，在**订阅主题**选项卡的**主题筛选条件**中，输入 **\$1**（井号），然后选择**订阅**以进行订阅。

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)