在本教程中,您使用 WebSocket API 创建一个无服务器广播应用程序。客户端可以接收消息,而无需轮询更新。
本教程介绍如何向连接的客户端广播消息,并包括 Lambda 授权方、模拟集成以及与 Step Functions 的非代理集成的示例。

使用 AWS CloudFormation 模板创建资源后,您将使用 API Gateway 控制台来创建与 AWS 资源集成的 WebSocket API。您需要将 Lambda 授权方附加到您的 API,并创建 AWS 服务与 Step Functions 的集成,才能启动状态机执行。Step Functions 状态机将调用一个 Lambda 函数,来向所有连接的客户端发送消息。
构建 API 后,您将测试到 API 的连接,并验证消息是否已发送和接收。完成本教程需要大约 45 分钟。
主题
先决条件
您需要以下先决条件:
-
拥有控制台访问权限的 AWS 账户和 AWS Identity and Access Management 用户。有关更多信息,请参阅 设置为使用 API Gateway。
-
要连接到您的 API 的
wscat
有关更多信息,请参阅 使用 wscat 连接到 WebSocket API 并向其发送消息。
我们建议您在开始本教程之前,完成 WebSocket 聊天应用程序教程。要完成 WebSocket 聊天应用程序教程,请参阅教程:使用 WebSocket API、Lambda 和 DynamoDB 创建 WebSocket 聊天应用程序。
步骤 1:创建资源
下载并解压缩适用于 AWS CloudFormation 的应用程序创建模板。您将使用此模板创建以下各项:
处理 API 请求并授权访问您的 API 的 Lambda 函数。
用于存储客户端 ID 和由 Lambda 授权方返回的主体用户标识的 DynamoDB 表。
用于向连接的客户端发送消息的 Step Functions 状态机。
创建 AWS CloudFormation 堆栈
打开 AWS CloudFormation 控制台,地址:https://console.aws.amazon.com/cloudformation
。 -
选择创建堆栈,然后选择使用新资源(标准)。
-
对于指定模板,选择上传模板文件。
-
选择您下载的模板。
-
选择下一步。
-
对于堆栈名称,输入
websocket-step-functions-tutorial
,然后选择下一步。 -
对于配置堆栈选项,请选择下一步。
-
对于功能,请确认 AWS CloudFormation 可以在您的账户中创建 IAM 资源。
-
选择提交。
AWS CloudFormation 预置在模板中指定的资源。完成资源预置可能需要几分钟时间。选择输出选项卡,来查看您创建的资源及其 ARN。当 AWS CloudFormation 堆栈的状态为 CREATE_COMPLETE 时,您就可以继续下一步了。
步骤 2:创建 WebSocket API
您将创建一个 WebSocket API 来处理客户端连接,并将请求路由到您在步骤 1 中创建的资源。
创建 WebSocket API
通过以下网址登录到 Amazon API Gateway 控制台:https://console.aws.amazon.com/apigateway
。 选择创建 API。对于 WebSocket API,选择构建。
对于 API 名称,请输入
websocket-step-functions-tutorial
。对于路由选择表达式,输入
request.body.action
。路由选择表达式确定当客户端发送消息时 API Gateway 调用的路由。
选择下一步。
对于预定义路由,选择添加 $connect、添加 $disconnect、添加 $default。
$connect 和 $disconnect 路由是 API Gateway 在客户端连接到 API 或断开与 API 的连接时自动调用的特殊路由。当没有其它路由与请求匹配时,API Gateway 调用 $default 路由。创建 API 后,您将创建一个连接到 Step Functions 的自定义路由。
选择下一步。
对于 $connect 的集成,请执行以下操作:
对于集成类型,选择 Lambda。
-
对于 Lambda 函数,选择您在步骤 1 中使用 AWS CloudFormation 创建的相应 $connect Lambda 函数。Lambda 函数名称应该以
websocket-step
开头。
对于 $disconnect 的集成,请执行以下操作:
对于集成类型,选择 Lambda。
-
对于 Lambda 函数,选择您在步骤 1 中使用 AWS CloudFormation 创建的相应 $disconnect Lambda 函数。Lambda 函数名称应该以
websocket-step
开头。
对于 $default 的集成,请选择模拟。
在模拟集成中,API Gateway 在没有集成后端的情况下管理路由响应。
选择下一步。
-
查看 API Gateway 为您创建的阶段。默认情况下,API Gateway 会创建名为生产的阶段,然后自动将您的 API 部署到该阶段。选择下一步。
选择创建和部署。
步骤 3:创建 Lambda 授权方
要控制对您的 WebSocket API 的访问权限,您需要创建 Lambda 授权方。AWS CloudFormation 模板为您创建了 Lambda 授权方函数。您可以在 Lambda 控制台中看到 Lambda 函数。名称应以 websocket-step-functions-tutorial-AuthorizerHandler
开头。除非 Authorization
标头是 Allow
,否则此 Lambda 函数会拒绝对 WebSocket API 的所有调用。Lambda 函数还会将 $context.authorizer.principalId
变量传递给您的 API,稍后会在 DynamoDB 表中使用该变量来标识 API 调用方。
在此步骤中,您将配置 $connect 路由来使用 Lambda 授权方。
创建 Lambda 授权方
通过以下网址登录到 Amazon API Gateway 控制台:https://console.aws.amazon.com/apigateway
。 在主导航窗格中,选择授权方。
选择创建授权方。
对于授权方名称,输入
LambdaAuthorizer
。对于授权方 ARN,输入由 AWS CloudFormation 模板创建的授权方的名称。名称应以
websocket-step-functions-tutorial-AuthorizerHandler
开头。注意
我们建议不要为生产 API 使用此示例授权方。
对于身份来源类型,选择标头。对于键,输入
Authorization
。选择创建授权方。
创建授权方后,将其附加到您的 API 的 $connect 路由。
将授权方附加到 $connect 路由
在主导航窗格中,选择路由。
选择 $connect 路由。
在路由请求设置部分中,选择编辑。
对于授权,请选择下拉菜单,然后选择您的请求授权方。
选择保存更改。
步骤 4:创建模拟双向集成
接下来,您将为 $default 路由创建双向模拟集成。模拟集成可让您在不使用后端的情况下向客户端发送响应。当您为 $default 路由创建集成时,您可以向客户端展示如何与 API 进行交互。
您可以配置 $default 路由来通知客户端使用 sendmessage 路由。
创建模拟请求
通过以下网址登录到 Amazon API Gateway 控制台:https://console.aws.amazon.com/apigateway
。 选择 $default 路由,然后选择集成请求选项卡。
对于请求模板,请选择编辑。
对于模板选择表达式,输入
200
,然后选择编辑。在集成请求选项卡上,对于请求模板,选择创建模板。
对于模板密钥,输入
200
。对于生成模板,输入以下映射模板:
{"statusCode": 200}
选择创建模板。
结果应该类似以下内容:
在 $default 路由窗格中,选择启用双向通信。
选择集成响应选项卡,然后选择创建集成响应。
对于响应密钥,输入
$default
。对于模板选择表达式,输入
200
。选择创建响应。
在响应模板下,选择创建模板。
对于模板密钥,输入
200
。对于响应模板,输入以下映射模板:
{"Use the sendmessage route to send a message. Connection ID: $context.connectionId"}
选择创建模板。
结果应该类似以下内容:
步骤 5:使用 Step Functions 创建非代理集成
接下来,创建 sendmessage 路由。客户端可以调用 sendmessage 路由,来向所有连接的客户端广播消息。sendmessage 路由已将非代理 AWS 服务与 AWS Step Functions 集成。该集成会针对 AWS CloudFormation 模板为您创建的 Step Functions 状态机调用 StartExecution 命令。
创建非代理集成
通过以下网址登录到 Amazon API Gateway 控制台:https://console.aws.amazon.com/apigateway
。 选择创建路由。
对于路由键,请输入
sendmessage
。对于集成类型,选择 AWS 服务。
对于 AWS 区域,输入您部署了 AWS CloudFormation 模板的区域。
对于 AWS 服务,选择 Step Functions。
对于 HTTP 方法,选择 POST。
对于操作名称,输入
StartExecution
。对于执行角色,输入由 AWS CloudFormation 模板创建的执行角色。名称应为 WebsocketTutorialApiRole。
选择创建路由。
接下来,您创建一个映射模板,来将请求参数发送到 Step Functions 状态机。
创建映射模板
选择 sendmessage 路由,然后选择集成请求选项卡。
在请求模板部分中,选择编辑。
对于模板选择表达式,输入
\$default
。选择编辑。
在请求模板部分,选择创建模板。
对于模板密钥,输入
\$default
。对于生成模板,输入以下映射模板:
#set($domain = "$context.domainName") #set($stage = "$context.stage") #set($body = $input.json('$')) #set($getMessage = $util.parseJson($body)) #set($mymessage = $getMessage.message) { "input": "{\"domain\": \"$domain\", \"stage\": \"$stage\", \"message\": \"$mymessage\"}", "stateMachineArn": "arn:aws:states:
us-east-2
:123456789012
:stateMachine:WebSocket-Tutorial-StateMachine" }将
stateMachineArn
替换为由 AWS CloudFormation 创建的状态机的 ARN。映射模板执行以下操作:
-
使用上下文变量
domainName
创建变量$domain
。 -
使用上下文变量
stage
创建变量$stage
。$domain
和$stage
变量是构建回调 URL 所必需的。 接收传入的
sendmessage
JSON 消息,并提取message
属性。-
为状态机创建输入。输入是 WebSocket API 的域和阶段以及来自
sendmessage
路由的消息。
-
-
选择创建模板。
您可以在 $connect 或 $disconnect 路由上创建非代理集成,来直接在 DynamoDB 表中添加或移除连接 ID,而无需调用 Lambda 函数。
步骤 6:测试您的 API
接下来,您将部署和测试您的 API 来确保它正常工作。您将使用 wscat
命令连接到 API,然后,您将使用斜杠命令发送 ping 帧来检查与 WebSocket API 的连接。
部署 API
通过以下网址登录到 Amazon API Gateway 控制台:https://console.aws.amazon.com/apigateway
。 在主导航窗格中,选择路由。
选择部署 API。
对于阶段,选择生产。
(可选)对于部署描述,输入描述。
选择部署。
部署 API 后,您可以调用它。使用调用 URL 来调用您的 API。
获取您的 API 的调用 URL
选择 API。
选择阶段,然后选择生产。
-
记下 API 的 WebSocket URL。该 URL 应类似于
wss://
。abcdef123
.execute-api.us-east-2
.amazonaws.com/production
现在您已经有了调用 URL,您可以测试与 WebSocket API 的连接了。
测试与您的 API 的连接
使用以下命令连接到您的 API。首先,通过调用
/ping
路径来测试连接。wscat -c wss://
abcdef123
.execute-api.us-east-2
.amazonaws.com/production -H "Authorization: Allow" --slash -PConnected (press CTRL+C to quit)
-
输入以下命令来 ping 控制帧。您可以从客户端使用控制帧来实现保持活动目的。
/ping
结果应该类似以下内容:
< Received pong (data: "")
现在您已经测试了连接,您可以测试 API 是否正常工作。在此步骤中,您打开一个新的终端窗口,以便 WebSocket API 可以向所有连接的客户端发送消息。
要测试您的 API
-
打开一个新终端并使用以下参数再次运行
wscat
命令。wscat -c wss://
abcdef123
.execute-api.us-east-2
.amazonaws.com/production -H "Authorization: Allow"Connected (press CTRL+C to quit)
-
API Gateway 根据 API 的路由请求选择表达式确定要调用的路由。您的 API 的路由选择表达式是
$request.body.action
。因此,当您发送以下消息时,API Gateway 会调用sendmessage
路由:{"action": "sendmessage", "message": "hello, from Step Functions!"}
与路由关联的 Step Functions 状态机使用消息和回调 URL 调用 Lambda 函数。Lambda 函数调用 API Gateway 管理 API,并将消息发送给所有连接的客户端。所有客户端都会收到以下消息:
< hello, from Step Functions!
现在您已经测试了 WebSocket API,可以断开与 API 的连接。
从 API 断开连接
按
CTRL+C
以从 API 断开连接。当客户端与 API 断开连接时,API Gateway 会调用 API 的 $disconnect 路由。适用于 API 的 $disconnect 路由的 Lambda 集成会从 DynamoDB 中删除连接 ID。
步骤 7:清除
为避免不必要的成本,请删除作为本教程的一部分而创建的资源。以下步骤将删除您的 AWS CloudFormation 堆栈和 WebSocket API。
删除 WebSocket API
通过以下网址登录到 Amazon API Gateway 控制台:https://console.aws.amazon.com/apigateway
。 在 API 页面上,选择您的 websocket-api。
选择操作,选择删除,然后确认您的选择。
删除 AWS CloudFormation 堆栈
打开 AWS CloudFormation 控制台,地址:https://console.aws.amazon.com/cloudformation
。 -
选择您的 AWS CloudFormation 堆栈。
-
选择删除,然后确认您的选择。
后续步骤
您可以自动创建和清理本教程中涉及的所有 AWS 资源。有关本教程中自动执行这些操作的 AWS CloudFormation 模板的示例,请参阅 ws-sfn.zip。