

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

# 教學：使用 WebSocket API、Lambda 和 DynamoDB 建立 WebSocket 聊天應用程式
<a name="websocket-api-chat-app"></a>

在本教學課程中，您將建立 WebSocket API 的無伺服器聊天應用程式。使用 WebSocket API，您可以支持客户端之間的雙向通訊。客户端無需輪詢來進行更新即可以接收訊息。

本教學課程需要約 30 分鐘的時間完成。首先，您將使用 CloudFormation 範本建立將處理 API 請求的 Lambda 函數，以及存放用戶端 IDs DynamoDB 資料表。然後，您將使用 API Gateway 主控台來建立與 Lambda 函數整合的 WebSocket API。最後，您將測試 API 以確認是否能傳送和接收訊息。

![\[您在本教學課程中所建立 API 的架構概觀。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/ws-chat-app.png)


若要完成本教學課程，您需要 AWS 帳戶和具有主控台存取權 AWS Identity and Access Management 的使用者。如需詳細資訊，請參閱[設定為使用 API Gateway](setting-up.md)。

您還需要 `wscat` 來連線到 API。如需詳細資訊，請參閱[使用 `wscat` 以連接到 WebSocket API 和將訊息傳送到其中](apigateway-how-to-call-websocket-api-wscat.md)。

**Topics**
+ [步驟 1：建立 Lambda 函數和 DynamoDB 資料表](#websocket-api-chat-app-create-dependencies)
+ [步驟 2：建立 WebSocket API](#websocket-api-chat-app-create-api)
+ [步驟 3：測試您的 API](#websocket-api-chat-app-invoke-api)
+ [步驟 4：清理](#websocket-api-chat-app-cleanup)
+ [後續步驟：使用 自動化 CloudFormation](#websocket-api-chat-app-next-steps)

## 步驟 1：建立 Lambda 函數和 DynamoDB 資料表
<a name="websocket-api-chat-app-create-dependencies"></a>

下載並解壓縮 [的應用程式建立範本 CloudFormation](samples/ws-chat-app-starter.zip)。您將使用此範本建立 Amazon DynamoDB 資料表，以存放您應用程式的用户端 ID。每個連線的用户端都有一個唯一 ID，我們將使用它作為資料表的分區索引鍵。此範本也建立 Lambda 函數，其用於更新 DynamoDB 中的客户端連線並處理傳送給連線客户端的訊息。

**建立 CloudFormation 堆疊**

1. 在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 選擇 **Create stack (建立堆疊)**，然後選擇 **With new resources (standard) (使用新資源 (標準))**。

1. 對於 **Specify template (指定範本)**，選擇 **Upload a template file (上傳範本檔案)**。

1. 選取您下載的範本。

1. 選擇 **Next** (下一步)。

1. 針對 **Stack name (堆疊名稱)**，輸入 **websocket-api-chat-app-tutorial**，然後選擇 **Next (下一步)**。

1. 針對 **Configure stack options (設定堆疊選項)**，選擇 **Next (下一步)**。

1. 針對 **功能**，確認 CloudFormation 可以在您的帳戶中建立 IAM 資源。

1. 選擇**下一步**，然後選擇**提交**。

CloudFormation 會佈建範本中指定的資源。完成資源佈建可能需要幾分鐘的時間。當您的 CloudFormation 堆疊狀態為 **CREATE\$1COMPLETE** 時，您就可以繼續進行下一個步驟。

## 步驟 2：建立 WebSocket API
<a name="websocket-api-chat-app-create-api"></a>

您將建立 WebSocket API 來處理客户端連線，並將請求路由到您在步驟 1 中建立的 Lambda 函數。



**若要建立 WebSocket API**

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 選擇 **Create API (建立 API)**。然後對於 **WebSocket API**，選擇 **Build (建置)**。

1. 對於 **API name (API 名稱)**，輸入 **websocket-chat-app-tutorial**。

1. 針對 **IP 位址類型**，選擇 **IPv4**。

1. 對於 **Route selection expression (路由選擇表達式)**，輸入 **request.body.action**。路由選取表達式用於決定當用戶端傳送訊息時 API Gateway 要叫用的路由。

1. 選擇**下一步**。

1. 對於 **Predefined routes (預先定義路由)**，選擇 **Add \$1connect (新增 \$1connect)**、**Add \$1disconnect (新增 \$1disconnect)**，以及 **Add \$1default (新增 \$1default)**。**\$1connect** 和 **\$1disconnect** 路由是 API Gateway 在用户端連線到 API 或中斷連線時自動叫用的特殊路由。當沒有其他路由與請求相符時，API Gateway 會叫用 `$default` 路由。

1. 對於 **Custom routes (自訂路由)**，選擇 **Add custom route (新增自訂路由)**。對於 **Route key (路由金鑰)**，輸入 **sendmessage**。此自定義路由會處理傳送到已連線用户端的訊息。

1. 選擇**下一步**。

1. 在 **Attach integrations (連接整合)** 下，為每個路由和 **Integration type (整合類型)** 選擇 Lambda。

   針對 **Lambda**，選擇您在步驟 1 CloudFormation 中使用 建立的對應 Lambda 函數。每個函數的名稱會與一個路由相符。例如，對於 **\$1connect** 路由，選擇名為 **websocket-chat-app-tutorial-ConnectHandler** 的函數。

1. 檢閱 API Gateway 為您建立的階段。依預設，API Gateway 會建立階段名稱 `production`，並自動將您的 API 部署到該階段。選擇**下一步**。

1. 選擇 **Create and deploy (建立和部署)**。

## 步驟 3：測試您的 API
<a name="websocket-api-chat-app-invoke-api"></a>

接著，您將測試您的 API 以確保其正常工作。若要連接至 API，請使用 `wscat` 命令。

**取得 URL 來叫用您的 API**

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 選擇您的 API。

1. 選擇 **Stages (階段)**，然後選擇 **production (產品)**。

1. 請注意 API 的 **WebSocket URL**。URL 看起來應該會像這樣：`wss://abcdef123.execute-api.us-east-2.amazonaws.com/production`。

**連線到您的 API**

1. 使用下列命令來連線到 API。當您連線到 API 時，API Gateway 會叫用 `$connect` 路由。當叫用此路由時，該路由會叫用可將連線 ID 存放在 DynamoDB 中的 Lambda 函數。

   ```
   wscat -c wss://abcdef123.execute-api.us-west-2.amazonaws.com/production
   ```

   ```
   Connected (press CTRL+C to quit)
   ```

1. 開啟新的終端機並使用下列參數再次執行 **wscat** 命令。

   ```
   wscat -c wss://abcdef123.execute-api.us-west-2.amazonaws.com/production
   ```

   ```
   Connected (press CTRL+C to quit)
   ```

   這將為您提供兩個可交換訊息的已連線用户端。

**傳送訊息**
+  API Gateway 根據 API 的路由選擇表達式確定要叫用的路由。您的 API 的路由選擇表達式是 `$request.body.action`。因此，當您傳送以下訊息時 API Gateway 會叫用 `sendmessage` 路由：

  ```
  {"action": "sendmessage", "message": "hello, everyone!"}
  ```

  與叫用路由相關聯的 Lambda 函數會從 DynamoDB 收集用户端 ID。然後，該函數會叫用 API Gateway Management API 並將訊息傳送到這些用户端。所有連線的用户端都會收到下列訊息：

  ```
  < hello, everyone!
  ```

**叫用您 API 的 \$1default 路由**
+ 當用户端傳送與您定義路由不相符的訊息時，API Gateway 會叫用 API 的預設路由。與 `$default` 路由相關聯的 Lambda 函數會使用 API Gateway Management API 傳送其連線相關的用户端資訊。

  ```
  test
  ```

  ```
  Use the sendmessage route to send a message. Your info: {"ConnectedAt":"2022-01-25T18:50:04.673Z","Identity":{"SourceIp":"192.0.2.1","UserAgent":null},"LastActiveAt":"2022-01-25T18:50:07.642Z","connectionID":"Mg_ugfpqPHcCIVA="}
  ```

**中斷與 API 的連線**
+ 若要中斷與 API 的連線，請按 **CTRL\$1C**。當用户端從 API 中斷連線時，API Gateway 會調用 API 的 `$disconnect` 路由。API 的 `$disconnect` 路由之 Lambda 整合會從 DynamoDB 移除連線 ID。

## 步驟 4：清理
<a name="websocket-api-chat-app-cleanup"></a>

若要避免不必要的成本，請刪除您在此教學課程中建立的資源。下列步驟會刪除您的 CloudFormation 堆疊和 WebSocket API。

**刪除 WebSocket API**

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 在 **APIs (API)** 頁面上，選取 `websocket-chat-app-tutorial` API。依次選擇 **Actions (動作)**、**Delete (刪除)**，然後確認您的選擇。

**刪除 CloudFormation 堆疊**

1. 在 https：//[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) 開啟 CloudFormation 主控台。

1. 選取您的 CloudFormation 堆疊。

1. 選擇**刪除**，然後確認您的選擇。

## 後續步驟：使用 自動化 CloudFormation
<a name="websocket-api-chat-app-next-steps"></a>

您可以自動化建立和清除本教學課程中涉及的所有 AWS 資源。如需建立此 API 和所有相關資源的 CloudFormation 範本，請參閱 [ws-chat-app.yaml。](samples/ws-chat-app.zip)