

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 WebSockets Amazon Chime SDK 訊息中接收訊息
<a name="websockets"></a>

 您可以使用 [Amazon Chime JS SDK](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 政策。下列範例政策提供建立 WebSocket 連線的`AppInstanceUser`許可。

```
"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 傳回的 URL 來建構簽章第 4 版簽署的 WebSocket URL。如果您需要協助執行此操作，您可以遵循 中的指示[建立連線](#connect-api)。
**注意**  
WebSocket URLs的格式如下： `id.region.ws-messaging.chime.aws`

## 建立連線
<a name="connect-api"></a>

 擷取端點之後，您可以使用連線 API 建立與 Amazon Chime SDK 後端伺服器的 WebSocket 連線，並接收 的訊息`AppInstanceUser`。您必須使用 AWS Signature 第 4 版來簽署請求。如需簽署請求的詳細資訊，請參閱[使用 Signature 第 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**

識別 AWS Signature 的版本，以及您用來計算簽章的演算法。Amazon Chime SDK 僅支援 AWS Signature 第 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：//[https://docs.aws.amazon.com/STS/latest/APIReference/](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html)。

**SessionId**

指出要建立之 WebSocket 連線的唯一 ID。

**UserArn**

指出`AppInstanceUser`嘗試建立連線的 身分。值應該是 的 ARN`AppInstanceUser`。例如 `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`事件。預先擷取功能隨附於連線 API，而 功能可讓使用者查看豐富的聊天檢視，而無需額外的 API 呼叫。使用者可以：
+ 查看最後一個頻道訊息的預覽，以及其時間戳記。
+ 查看頻道的成員。
+ 查看頻道的未讀取標記。

使用者連線到指定的預先擷取參數後，使用者會收到工作階段建立的事件，這表示已建立連線。然後，使用者會收到最多 50 個`CHANNEL_DETAILS`事件。如果使用者的頻道少於 50 個，連線 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`使用者中斷連線時，訊息會停止。

`AppInstanceAdmin` 和 `ChannelModerator`不會在頻道上接收訊息，除非您使用 [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 明確新增。

下列主題說明如何處理事件。

**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_tw/chime-sdk/latest/dg/websockets.html)

**x-amz-chime-message-type**  
下表列出`x-amz-chime-message-type`訊息類型 。


| 訊息類型 | Description | 
| --- | --- | 
| `STANDARD` | 當 Websocket 收到 STANDARD 頻道訊息時傳送。 | 
| `CONTROL` | 當 WebSocket 收到 CONTROL 頻道訊息時傳送。 | 
| `SYSTEM` | Amazon Chime SDK Messaging 傳送的所有其他 Websocket 訊息。 | 

**x-amz-chime-event-reason**  
這是特定使用案例支援的選用標頭。標頭提供有關為何收到特定事件的資訊。


| 事件原因 | Description | 
| --- | --- | 
| subchannel\$1DELETED | `DELETE_CHANNEL_MEMBERSHIP` 彈性頻道主持人收到的事件。只有在成員資格平衡之後，主持人才會看到 會刪除其所屬的子頻道。 | 

### 處理中斷連線
<a name="handle-disconnects"></a>

Websocket 可能因網路連線變更或憑證過期而中斷連線。開啟 WebSocket 之後，Amazon Chime SDK 會將一般 ping 傳送至訊息用戶端，以確保其仍保持連線。如果連線關閉，用戶端會收到 WebSocket 關閉程式碼。用戶端可以嘗試重新連線，也可以不重新連線，具體取決於關閉程式碼。下表顯示用戶端可用來重新連線的關閉代碼。

對於 1000 到 4000 關閉碼，請僅針對下列訊息重新連線：


| 關閉代碼 | 可以重新連線 | Reason | 
| --- | --- | --- | 
| 1001 | 是 | 正常關閉 | 
| 1006 | 是 | 異常關閉 | 
| 1011 | 是 | 內部伺服器錯誤 | 
| 1012 | 是 | 服務重新啟動 | 
| 1013 | 是 | 稍後再試一次 | 
| 1014 | 是 | 伺服器做為閘道或代理，並從上游伺服器收到無效的回應。這類似於 502 HTTP 狀態碼。 | 

對於 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. 透過 WebSocket 連線。

如果您使用 amazon-chime-sdk-js 程式庫，如果您實作 [needsRefresh()](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Credentials.html#needsRefresh-property) 屬性和 [refresh()](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Credentials.html#refresh-property) 方法，則會為您處理。如需工作範例，請參閱 https：//[https://github.com/aws-samples/amazon-chime-sdk/blob/dc11c4c76c78d28f618577706bba2087919a5635/apps/chat/src/providers/AuthProvider.jsx\$1L93-L101](https://github.com/aws-samples/amazon-chime-sdk/blob/dc11c4c76c78d28f618577706bba2087919a5635/apps/chat/src/providers/AuthProvider.jsx#L93-L101)。