

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

# 在应用程序和服务中使用影子
<a name="device-shadow-comms-app"></a>

本节介绍应用程序或服务如何与 Dev AWS IoT ice Shadow 服务进行交互。该示例假定应用程序或服务仅与影子进行交互，并通过影子与设备进行交互。该示例不包括任何管理操作，例如创建或删除影子。

此示例使用 Dev AWS IoT ice Shadow 服务的 REST API 与阴影进行交互。与中使用的示例不同[在设备中使用影子](device-shadow-comms-device.md)，后者使用 REST API 的publish/subscribe communications model, this example uses the request/response通信模型。这意味着应用程序或服务必须先发出请求，然后才能收到来自的响应 AWS IoT。但该模型的一个缺点是，它不支持通知。如果您的应用程序或服务需要及时通知设备状态变化，请考虑支持 publish/subscribe 通信模型的 MQTT 或 MQTT over WSS 协议，如中所述。[在设备中使用影子](device-shadow-comms-device.md)

**重要**  
确保应用程序或服务使用的影子与设备中的相应实施保持一致，并且该实施支持使用这些影子。例如，考虑如何创建、更新和删除影子，以及如何在设备以及访问影子的应用程序或服务中处理更新。您的设计应明确指定如何更新和报告设备的状态，以及应用程序和服务如何与设备及其影子进行交互。

命名的影子的 REST API URL 为：

```
https://endpoint/things/thingName/shadow?name=shadowName
```

未命名的影子的 REST API URL 为：

```
https://endpoint/things/thingName/shadow
```

其中：

端点  
CLI 命令返回的端点：  

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

thingName  
影子所属的事物对象的名称

shadowName  
命名的影子的名称。该参数不用于未命名的影子。

## 在连接到时初始化应用程序或服务 AWS IoT
<a name="device-shadow-comms-app-first-connect"></a>

当应用程序首次连接到时 AWS IoT，它应该向其使用的阴影发送一个 HTTP GET 请求，以获取其正在使用的阴影的当前状态。 URLs 这样，它就可以将应用程序或服务同步到影子。

## 应用程序或服务连接时处理状态会发生变化 AWS IoT
<a name="device-shadow-comms-app-while-connected"></a>

当应用程序或服务连接到时 AWS IoT，它可以通过对其使用的阴影发送 HTTP GET 请求来定期查询当前状态。 URLs 

当最终用户与应用程序或服务交互以更改设备的状态时，该应用程序或服务可以向其用来更新影子`desired`状态 URLs 的影子发送 HTTP POST 请求。该请求返回已接受的更改，但您可能需要发出 HTTP GET 请求以轮询影子，直到设备使用新状态更新了影子为止。

## 检测是否连接了设备
<a name="thing-connection"></a>

要确定当前是否连接了设备，请在影子文档中包含一个 `connected` 属性；如果设备由于错误而断开连接，则使用 MQTT Last Will and Testament (LWT) 消息将 `connected` 属性设置为 `false`。

**注意**  
Dev AWS IoT ice Shadow 服务会忽略发送到 AWS IoT 保留主题（以 \$1 开头的主题）的 MQTT LWT 消息。但是，它们由订阅的客户端和 AWS IoT 规则引擎处理，因此您需要创建一条发送到非保留主题的 LWT 消息和一条规则，将 MQTT LWT 消息作为影子更新消息重新发布到影子的保留更新主题。`ShadowTopicPrefix/update`

**向 Device Shadow 服务发送 LWT 消息**

1. 创建一个规则以在保留的主题上重新发布 MQTT LWT 消息。以下示例规则会侦听关于 `my/things/myLightBulb/update` 主题的消息并其重新发布到 `$aws/things/myLightBulb/shadow/update`。

   ```
   {
       "rule": {
       "ruleDisabled": false,
       "sql": "SELECT * FROM 'my/things/myLightBulb/update'",
       "description": "Turn my/things/ into $aws/things/",
       "actions": [
           {
           "republish": {
               "topic": "$$aws/things/myLightBulb/shadow/update",
               "roleArn": "arn:aws:iam:123456789012:role/aws_iot_republish"
               }
           }
        ]
      }
   }
   ```

1. 当设备连接到时 AWS IoT，它会向非保留主题注册一条 LWT 消息，以供重新发布规则识别。在此示例中，该主题为 `my/things/myLightBulb/update`，它将 connected 属性设置为 `false`。

   ```
   {
       "state": {        
           "reported": {
               "connected":"false"
           }
       }
   }
   ```

1. 在连接后，设备在其影子更新主题 `$aws/things/myLightBulb/shadow/update` 上发布消息以报告其当前状态，这包括将其 `connected` 属性设置为 `true`。

   ```
   {
        "state": {        
           "reported": {
               "connected":"true"
           }
       }
   }
   ```

1. 在设备正常断开连接之前，它在其影子更新主题 `$aws/things/myLightBulb/shadow/update` 上发布消息以报告其最新状态，这包括将其 `connected` 属性设置为 `false`。

   ```
   {
       "state": {        
           "reported": {
               "connected":"false"
           }
       }
   }
   ```

1. 如果设备因错误而断开连接， AWS IoT 消息代理将代表设备发布设备的 LWT 消息。重新发布规则检测该消息，并发布影子更新消息以更新设备影子的 `connected` 属性。

**注意**  
由于断开连接处理的异步性质，无法保证 LWT 消息在重新连接期间按顺序分发。我们建议您使用[生命周期事件](life-cycle-events.md)来提高连接状态检测的准确性，因为这些事件提供了管理 out-of-order事件的属性。