

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

# 生命周期事件
<a name="life-cycle-events"></a>

Amazon IoT 可以发布有关 MQTT 主题的生命周期事件。这些事件在默认情况下可用，且不能被禁用。

**注意**  
生命周期消息可能不会按顺序发送。您可能会收到重复的消息。  
`thingName` 仅当客户端使用[独占事物](exclusive-thing.md)功能连接时才会包含。

**Topics**
+ [连接/断开连接事件](#connect-disconnect)
+ [连接尝试失败事件](#connect-authfailure-event)
+ [订阅/取消订阅事件](#subscribe-unsubscribe-events)

## 连接/断开连接事件
<a name="connect-disconnect"></a>

**注意**  
借助 Amazon IoT 设备管理队列索引，您可以搜索事物、运行聚合查询以及基于事物 Connect/Disconnect 事件创建动态组。有关更多信息，请参阅[实例集索引](https://docs.amazonaws.cn//iot/latest/developerguide/iot-indexing.html)。

Amazon IoT 当客户端连接或断开连接时，向以下 MQTT 主题发布消息：
+ `$aws/events/presence/connected/clientId` - 连接到消息代理的客户端。
+ `$aws/events/presence/disconnected/clientId` - 与消息代理断开连接的客户端。

以下是发布到该`$aws/events/presence/connected/clientId`主题的 connection/disconnection 消息中包含的 JSON 元素列表。

**clientId**  
建立连接或断开连接的客户端的 ID。  
包 IDs 含 \$1 或 \$1 的客户端不会收到生命周期事件。

**thingName**  
您的物联网事物的名称。`thingName` 仅当客户端使用[独占事物](exclusive-thing.md)功能连接时才会包含。

**clientInitiatedDisconnect**  
如果客户端启动断开连接，则为 true。否则为 false。只能在断开连接消息中找到。

**disconnectReason**  
客户端断开连接的原因。只能在断开连接消息中找到。下表包含有效值，以及在断开连接时代理是否会发送 [Last Will and Testament（LWT）消息](mqtt.md#mqtt-lwt)。      
[\[See the AWS documentation website for more details\]](http://docs.amazonaws.cn/iot/latest/developerguide/life-cycle-events.html)
1 如果设备在收到此错误之前连接处于活动状态。  
2 为防止出现 Last Will and Testament（LWT）消息，设置 `preventWillMessage=true` 以覆盖 `DeleteConnection` API 的默认 LWT 发送行为。

**eventType**  
事件类型。有效值为 `connected` 或 `disconnected`。

**ipAddress**  
连接客户端的 IP 地址。这可以是 IPv4 或 IPv6格式。只能在连接消息中找到。

**principalIdentifier**  
用于执行身份验证的凭证。对于 TLS 双向身份验证证书，这是证书 ID。对于其它连接，这是 IAM 凭证。

**sessionIdentifier**  
在会话生命周期中 Amazon IoT 存在的全局唯一标识符。

**timestamp**  
事件发生时间的近似值。

**versionNumber**  
生命周期事件的版本号。对于每个客户端 ID 连接，这是一个单调递增的长整数值。订阅者可以使用版本号来推断生命周期事件的顺序。  
客户端连接的连接和断开消息具有相同的版本号。  
版本号可能会跳过值，而不保证对于每个事件始终增加 1。  
如果客户端约一小时未连接，则版本号将重置为 0。对于持续会话，当客户端断开连接的时间超过为持续会话配置的 time-to-live (TTL) 时间后，版本号将重置为 0。

连接消息具有以下结构。

```
{
    "clientId": "186b5",
    "thingName": "exampleThing",
    "timestamp": 1573002230757,
    "eventType": "connected",
    "sessionIdentifier": "00000000-0000-0000-0000-000000000000",
    "principalIdentifier": "12345678901234567890123456789012",
    "ipAddress": "192.0.2.0",
    "versionNumber": 0
}
```

断开连接消息具有以下结构。

```
{
    "clientId": "186b5",
    "thingName": "exampleThing",
    "timestamp": 1573002340451,
    "eventType": "disconnected",
    "sessionIdentifier": "00000000-0000-0000-0000-000000000000",
    "principalIdentifier": "12345678901234567890123456789012",
    "clientInitiatedDisconnect": true,
    "disconnectReason": "CLIENT_INITIATED_DISCONNECT",
    "versionNumber": 0
}
```

### 处理客户端断开连接
<a name="reconnect"></a>

最佳实践是始终为生命周期事件实现等待状态，包括 [Last Will and Testament（LWT）消息](mqtt.md)。收到断开连接消息后，您的代码应等待一段时间，并在采取措施之前验证设备是否仍处于脱机状态。实现此目标的一种方法是使用 [SQS 延迟队列](https://docs.amazonaws.cn/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-delay-queues.html)。当客户端收到 LWT 或生命周期事件时，您可以将消息列入队列进行排队（例如 5 秒）。当消息可用并被处理（通过 Lambda 或其它服务）时，您可以先检查设备是否仍处于离线状态，然后再采取进一步操作。

## 连接尝试失败事件
<a name="connect-authfailure-event"></a>

Amazon IoT 当客户端无权连接，或者配置了遗嘱和遗嘱并且客户端无权发布到最后一个遗嘱主题时，会向以下 MQTT 主题发布消息。

```
$aws/events/presence/connect_failed/clientId
```

以下是发布到 `$aws/events/presence/connect_failed/clientId` 主题的连接授权消息中包含的 JSON 元素列表。

**clientId**  
尝试连接但失败的客户端的客户端 ID。  
包 IDs 含 \$1 或 \$1 的客户端不会收到生命周期事件。

**thingName**  
您的物联网事物的名称。`thingName` 仅当客户端使用[独占事物](exclusive-thing.md)功能连接时才会包含。

**timestamp**  
事件发生时间的近似值。

**eventType**  
事件类型。有效值为 `connect_failed`。

**connectFailureReason**  
连接失败的原因。有效值为 `AUTHORIZATION_FAILED`。

**principalIdentifier**  
用于执行身份验证的凭证。对于 TLS 双向身份验证证书，这是证书 ID。对于其它连接，这是 IAM 凭证。

**sessionIdentifier**  
在会话生命周期中 Amazon IoT 存在的全局唯一标识符。

**ipAddress**  
连接客户端的 IP 地址。这可以是 IPv4 或 IPv6格式。只能在连接消息中找到。

连接失败消息具有以下结构。

```
{
    "clientId": "186b5",
    "thingName": "exampleThing",
    "timestamp": 1460065214626,
    "eventType": "connect_failed",
    "connectFailureReason": "AUTHORIZATION_FAILED",
    "principalIdentifier": "12345678901234567890123456789012",
    "sessionIdentifier": "00000000-0000-0000-0000-000000000000",
    "ipAddress" : "192.0.2.0"
}
```

## 订阅/取消订阅事件
<a name="subscribe-unsubscribe-events"></a>

Amazon IoT 当客户端订阅或取消订阅 MQTT 主题时，向以下 MQTT 主题发布消息：

```
$aws/events/subscriptions/subscribed/clientId
```

 或者 

```
$aws/events/subscriptions/unsubscribed/clientId
```

其中 `clientId` 是连接到 Amazon IoT 消息代理的 MQTT 客户端 ID。

发布到该主题的消息具有以下结构：

```
{
    "clientId": "186b5",
    "thingName": "exampleThing",
    "timestamp": 1460065214626,
    "eventType": "subscribed" | "unsubscribed",
    "sessionIdentifier": "00000000-0000-0000-0000-000000000000",
    "principalIdentifier": "12345678901234567890123456789012",
    "topics" : ["foo/bar","device/data","dog/cat"]
}
```

下面是一系列 JSON 元素，发布到 `$aws/events/subscriptions/subscribed/clientId` 和 `$aws/events/subscriptions/unsubscribed/clientId` 主题的已订阅/未订阅消息中包含这些元素。

clientId  
订阅或取消订阅的客户端的 ID。  
包 IDs 含 \$1 或 \$1 的客户端不会收到生命周期事件。

thingName  
您的物联网事物的名称。`thingName` 仅当客户端使用[独占事物](exclusive-thing.md)功能连接时才会包含。

eventType  
事件类型。有效值为 `subscribed` 或 `unsubscribed`。

principalIdentifier  
用于执行身份验证的凭证。对于 TLS 双向身份验证证书，这是证书 ID。对于其它连接，这是 IAM 凭证。

sessionIdentifier  
在会话生命周期中 Amazon IoT 存在的全局唯一标识符。

timestamp  
事件发生时间的近似值。

主题  
客户端已订阅的一系列 MQTT 主题。

**注意**  
生命周期消息可能不会按顺序发送。您可能会收到重复的消息。