

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

# WebSockets 用于在 Amazon Chime 软件开发工具包消息中接收消息
<a name="websockets"></a>

 您可以使用 [Amazon Chime JS 软件开发工具包](https://github.com/aws/amazon-chime-sdk-js)通过接收消息 WebSockets，也可以使用您选择的 WebSocket 客户端库。

按照列出的顺序遵循以下主题开始使用 WebSockets：

**Topics**
+ [定义 IAM 策略](#define-iam-policy)
+ [检索终端节点](#retrieve-endpoint)
+ [建立连接](#connect-api)
+ [使用预提取来传送频道详情](#prefetch)
+ [处理事件](#process-events)

## 定义 IAM 策略
<a name="define-iam-policy"></a>

首先，定义一个允许您建立 WebSocket 连接的 IAM 策略。以下示例策略`AppInstanceUser`授予建立 WebSocket连接的权限。

```
"Version": "2012-10-17",		 	 	 
"Statement": [
  {
    "Effect": "Allow",
    "Action: [
      "chime:Connect"
    ],
    "Resource": [
      "arn:aws:chime:region:{aws_account_id}:app-instance/{app_instance_id}/user/{app_instance_user_id}"
    ]
 },
 {
    "Effect": "Allow",
    "Action: [
      "chime:GetMessagingSessionEndpoint"
    ],
    "Resource": [
      "*"
    ]
 }
 ]
}
```

## 检索终端节点
<a name="retrieve-endpoint"></a>

以下步骤说明如何检索 WebSocket连接中使用的端点。

1. 使用 [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html)API 检索 WebSocket 端点。

1. 使用 [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html)API 返回的网址来构造签名版本 4 的签名 WebSocket 网址。如果您需要帮助，可以按照 [建立连接](#connect-api) 中的说明进行操作。
**注意**  
WebSocket URLs 有以下形式：`id.region.ws-messaging.chime.aws`

## 建立连接
<a name="connect-api"></a>

 检索终端节点后，您可以使用 WebSocket 连接 API 建立与 Amazon Chime SDK 后端服务器的连接并接收消息。`AppInstanceUser`您必须使用 AWS 签名版本 4 来签署请求。有关对请求进行签名的更多信息，请参阅[利用签名版本 4 对 AWS 请求进行签名](https://docs.aws.amazon.com/general/latest/gr/Signature Version 4_signing.html)。

**注意**  
要检索端点，您可以调用 [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html) API。您可以使用自己选择的 WebSocket 客户端库连接到终端节点。

**请求语法**

```
GET /connect
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=AKIARALLEXAMPLE%2F20201214%2Fregion%2Fchime%2Faws4_request
&X-Amz-Date=20201214T171359Z
&X-Amz-Expires=10
&X-Amz-SignedHeaders=host
&sessionId={sessionId}
&userArn={appInstanceUserArn}
&X-Amz-Signature=db75397d79583EXAMPLE
```

**URI 请求参数**

所有 URI 请求查询参数都必须经过 URL 编码。

**X-Amz-Algorithm**

标识 S AWS ignature 的版本和用于计算签名的算法。Amazon Chime SDK 仅支持 AWS 签名版本 4 身份验证，因此其值是 `AWS4-HMAC-SHA256`。

**X-Amz-Credential**

除了您的访问密钥 ID 之外，此参数还提供签名有效的 AWS 区域和服务（范围）。该值必须与您在签名计算中使用的范围匹配。该参数值的一般形式为：

`<yourAccessKeyId>/<date>/<awsRegion>/<awsService >/aws4_request`

例如：

`AKIAIOSFODNN7EXAMPLE/20201214/us-east-1/chime/aws4_request`

**X-Amz-Date**

日期和时间格式必须遵循 ISO 8601 标准，并且您必须按照 `yyyyMMddTHHmmssZ` 将其格式化。例如，您必须将 **08/01/2020 15:32:41.982-700** 转换为协调世界时 (UTC) 并将其提交为 `20200801T083241Z`。

**X-Amz-Signed-Headers**

列出用于计算签名的标头。签名计算中需要以下标头：
+ HTTP 主机标头。
+ 您计划添加到请求的任何 x-amz-\$1 标头。

**注意**  
为了提高安全性，签署计划在请求中包含的所有请求标头。

**X-Amz-Signatures**

提供签名以验证您的请求。此签名必须与 Amazon Chime SDK 计算的签名相匹配。如果没有，Amazon Chime SDK 会拒绝该请求。例如 `733255ef022bec3f2a8701cd61d4b371f3f28c9f19EXAMPLEd48d5193d7`。

**X-Amz-Security-Token**

如果使用来自 Security Token Service 的凭证，则为可选凭证参数。有关该服务的更多信息，请参阅 [https://docs.aws.amazon.com/STS/latest/ APIReference](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html)。

**SessionId**

表示正在建立的 WebSocket 连接的唯一 ID。

**UserArn**

表示尝试建立连接的 `AppInstanceUser` 的身份。该值应为 `AppInstanceUser` 的 ARN。例如，`arn:aws:chime:us%2Deast%2D1:123456789012:app%2Dinstance/694d2099%2Dcb1e%2D463e%2D9d64%2D697ff5b8950e/user/johndoe`

## 使用预提取来传送频道详情
<a name="prefetch"></a>

建立 WebSocket 连接时，可以在查询`prefetch-on=connect`中指定传递`CHANNEL_DETAILS`事件的参数。Connect API 附带了预提取功能，该功能使用户无需额外的 API 调用即可查看丰富的聊天视图。用户可以：
+ 查看上一条频道消息的预览及其时间戳。
+ 查看频道的成员。
+ 查看频道的未读标记。

用户使用指定的预提取参数进行连接后，该用户会收到会话已建立事件，该事件表示连接已建立。然后，用户最多可接收 50 个 `CHANNEL_DETAILS` 事件。如果用户的频道少于 50 个，则 Connect API 会通过 `CHANNEL_DETAILS` 事件预提取所有频道。如果用户有超过 50 个频道，则 API 会预提取包含未读消息的前 50 个频道和最新 `LastMessageTimestamp` 值。`CHANNEL_DETAILS` 事件按随机顺序到达，您会收到所有 50 个频道的事件。

此外，预提取还会返回 `ChannelMessages` 和 `ChannelMemberships` 的以下内容：
+ **ChannelMessages** — [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMessageSummary.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMessageSummary.html) 对象列表，按 `CreatedTimestamp` 以降序排列。仅包括用户可见的最新 20 条消息。如果频道中存在当前用户看不到的定向消息，则返回的消息可能少于 20 条。`ChannelMessagesHasMore` 布尔值将设置为 true 以表示还有更多消息。软限额，可在 AWS 账户层面进行调整。
+ **ChannelMemberships** — [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMembershipSummary.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMembershipSummary.html) 对象列表。最多包含 30 个频道成员。软限额，可在 AWS 账户层面进行调整。

此示例介绍了如何使用 `prefetch-on=connect`：

```
GET /connect
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=AKIARALLEXAMPLE%2F20201214%2Fregion%2Fchime%2Faws4_request
&X-Amz-Date=20201214T171359Z
&X-Amz-Expires=10
&X-Amz-SignedHeaders=host
&sessionId=sessionId
&prefetch-on=connect
&userArn=appInstanceUserArn
&X-Amz-Signature=db75397d79583EXAMPLE
```

此示例介绍了一个频道的响应。您将收到所有 50 个频道的回复。

```
{
   "Headers": { 
        "x-amz-chime-event-type": "CHANNEL_DETAILS", 
        "x-amz-chime-message-type": "SYSTEM" 
        },
   "Payload": JSON.stringify"({
        Channel: [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelSummary.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelSummary.html) 
        ChannelMessages: List of [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMessageSummary.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMessageSummary.html)  
        ChannelMemberships: List of [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMembershipSummary.html ](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_ChannelMembershipSummary.html )
        ReadMarkerTimestamp: Timestamp 
        ChannelMessagesHasMore: Boolean 
    })
}
```

## 处理事件
<a name="process-events"></a>

对于在建立连接后才可接收消息的 `AppInstanceUser`，您必须将其添加到频道中。要执行这一操作，请使用 [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannelMembership.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannelMembership.html) API。

**注意**  
`AppInstanceUser` 始终接收其所属各频道的消息。当 `AppInstance` 用户断开连接时，消息传递将停止。

除非您使用 [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannelMembership.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_CreateChannelMembership.html) API 明确添加消息，否则 `AppInstanceAdmin` 和 `ChannelModerator` 不会在频道上接收消息。

下面的主题说明了如何处理事件。

**Topics**
+ [了解消息结构](#message-structures)
+ [处理断开连接](#handle-disconnects)

### 了解消息结构
<a name="message-structures"></a>

您收到的每 WebSocket 封邮件都遵循以下格式：

```
{
   "Headers": {"key": "value"},
   "Payload": "{\"key\": \"value\"}"
}
```

**标头**  
Amazon Chime SDK 消息传递使用以下标头键：
+ `x-amz-chime-event-type`
+ `x-amz-chime-message-type`
+ `x-amz-chime-event-reason`

下一节列出并描述了标头的可能值和有效负载。

**有效载荷**  
Websocket 消息返回 JSON 字符串。JSON 字符串的结构取决于 `x-amz-event-type` 标头。下表列出了可能的 `x-amz-chime-event-type` 值和有效负载：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/chime-sdk/latest/dg/websockets.html)

**x-amz-chime-message-类型**  
下表列出了 `x-amz-chime-message-type` 消息类型。


| 消息类型 | 说明 | 
| --- | --- | 
| `STANDARD` | 在 WebSocket 收到标准频道消息时发送。 | 
| `CONTROL` | 在 WebSocket 收到控制频道消息时发送。 | 
| `SYSTEM` | Amazon Chime SDK 消息传递发送的所有其他 WebSocket 消息。 | 

**x-amz-chime-event-原因**  
这是特定用例支持的可选标头。标头提供有关接收特定事件的原因的信息。


| 事件原因 | 说明 | 
| --- | --- | 
| subchannel\$1DELETED | 弹性频道监管人收到的 `DELETE_CHANNEL_MEMBERSHIP` 事件。只有在成员资格平衡删除他们所属的子频道后，监管人才能看见。 | 

### 处理断开连接
<a name="handle-disconnects"></a>

WebSocket 可能会因网络连接变化或凭证过期而断开连接。打开后 WebSocket，Amazon Chime 软件开发工具包会定期向消息客户端发送 ping，以确保其仍处于连接状态。如果连接关闭，客户端将收到 WebSocket 关闭代码。客户端可以尝试也可以不尝试重新连接，具体取决于关闭代码。下表显示了客户端可用于重新连接的关闭代码。

对于关闭代码 1000 至 4000，仅针对以下消息重新连接：


| 关闭代码 | 是否可以重新连接 | Reason | 
| --- | --- | --- | 
| 1001 | 是 | 正常关闭 | 
| 1006 | 是 | 异常关闭 | 
| 1011 | 是 | 内部服务器错误 | 
| 1012 | 是 | 服务重新启动 | 
| 1013 | 是 | 请稍后再试 | 
| 1014 | 是 | 服务器充当网关或代理，收到来自上游服务器的无效响应。这与 HTTP 状态代码 502 类似。 | 

对于 4XXX 代码，请务必重新连接，但以下消息*除外*：


| 关闭代码 | 是否可以重新连接 | Reason | 
| --- | --- | --- | 
| 4002 | 否 | 客户端已启动 | 
| 4003 | 否 | 禁止 | 
| 4401 | 否 | 未授权 | 

当应用程序使用关闭代码来重新连接时，应用程序应执行以下操作：

1. 再次调用 [https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html](https://docs.aws.amazon.com/chime-sdk/latest/APIReference/API_messaging-chime_GetMessagingSessionEndpoint.html) API 以获取新的基本 URL。

1. 如果 IAM 凭证已过期，请刷新它们。

1. 通过 Connect 连接 WebSocket。

[如果您使用该 amazon-chime-sdk-js库，则在实现 ne [edsRefresh () 属性和 refresh ()](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Credentials.html#needsRefresh-property) 方法时会为您处理此问题。](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Credentials.html#refresh-property)有关工作示例，请参见 [https://github.com/aws-samples/amazon-chime-sdk/blob/dc11c4c76c78d28f618577706bba2087919a5635/apps/chat/src/providers/AuthProvider.jsx \$1L93](https://github.com/aws-samples/amazon-chime-sdk/blob/dc11c4c76c78d28f618577706bba2087919a5635/apps/chat/src/providers/AuthProvider.jsx#L93-L101)-L101。