AWS API Gateway Websockets——connectionID 在哪里?

Big*_*ian 12 amazon-web-services websocket aws-api-gateway api-gateway

我正在 $connect 路由上设置一个带有自定义授权方的 AWS API Gateway Websockets,如下所述:

https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-route-keys-connect-disconnect.html

我的问题是——我如何获得 connectionID,即我可以用来稍后向该连接的客户端广播的标识符?

小智 14

要将内容添加到集成请求,您需要使用请求模板。

  1. 为您的路由关闭 HTTP 代理集成。(否则您无法修改请求。)
  2. 保存您的更改。(在您这样做之前,“请求模板”部分不会出现。)
  3. 设置您的模板选择表达式。这用于从传入的请求对象中查找值。(如果要匹配所有传入的请求,请输入\$default。注意斜线。此处为完整文档。)
  4. 设置您的模板密钥。这与模板选择表达式选择的值进行比较。如果匹配,则使用模板。(如果要匹配所有传入请求,请输入$default。注意没有斜线。)
  5. 单击您的模板密钥以打开模板编辑器。您可以在此处输入模板,该模板将作为请求正文发送到您的集成端点。例如,如果要将连接 ID 和传入查询参数转发到集成端点,则可以使用以下内容:
{
    "myConnectionIdProperty": "$context.connectionId",
    "myQueryParams": $input.params()
}
Run Code Online (Sandbox Code Playgroud)

可以在此处找到模板表达式中可用的变量文档。

(请注意,虽然$request是模板选择表达式中的有效变量,但它不是模板本身中的有效变量。请$input在此处改用。)


Fry*_*wow 10

要解决此问题,请转到 AWS 控制台 -> 打开 AWS CloudShell(仪表板右上角)

对于使用HTTP_PROXY的WebSocket服务器,需要修改@connect路由添加connectionId

1- 在 shell 中输入:

# List all integrations

aws apigatewayv2 get-integrations --api-id xxxxxxxxx

# Update all @connect integration

aws apigatewayv2 update-integration --integration-id zzzzzzzz --api-id xxxxxxxxx --request-parameters 'integration.request.header.connectionId'='context.connectionId'
Run Code Online (Sandbox Code Playgroud)

2-不要忘记之后部署,否则它将不起作用

为什么AWS不向您提供connectionId?因为他们希望你使用 Lambda。


Vin*_*wal 9

感谢大家尝试记录 AWS API Gateway。

为了能够使用 VPC Link 将数据从 AWS Websocket API Gateway 发送到您的集成服务,请执行以下操作:

  1. 取消选中使用代理集成

  2. 节省

  3. 如下图设置请求模板: AWS Websocket API 网关的请求模板设置

  4. 这将允许在请求正文中获取 connectionId、查询、正文。

  5. 节省

  6. 点击添加合并响应右上方

  7. 如下图所示设置集成响应积分响应设置

8. 希望它会起作用。如果没有,请通过测试找出答案,然后在此处为其他人提供答案。谢谢你。

我建议忘记任何其他类型的集成,只使用 lambda。因为您将面临的下一个问题是获取在断开连接集成中连接时传递的查询参数。


Big*_*ian 7

这里的问题是当使用 HTTP 作为集成类型时——即,当调用一个或多个 API GW 路由($connect/$disconnect/$invoke)时,http 端点被命中。我们发现我们无法代理请求(意味着我们丢失了原始标头,包括身份验证),但是如果我们需要连接 ID,我们必须指定一个请求模板并使用类似的东西:

{"connectionId": "$context.connectionId", "body": "$input.body"}


Fra*_*ark 6

这个问题没有具体说明使用什么类型的后端。AWS API Gateway 的 AWS 文档面向 lambda 函数 - 我找不到任何帮助来将 connectionId 获取到我的 http 后端。

尝试 Big Endian 的答案,我发现了一些问题 - 我的 cakephp 后端无法解码引用的 json 正文。我找到了解决方案,但实施他的答案还需要许多其他步骤,因此它们是:

我在关闭 HTTP 代理的情况下创建了一个路由键,并按如下方式设置了一个请求模板(也是非常稀疏的文档):

  • 路由选择表达式:$request.body.action
  • 路由键: subscribe
    这意味着所有带有 {"action": "subscribe"} 的请求都将通过这里路由

  • 集成请求类型:HTTP

  • HTTP 代理集成:关闭 - 到标头或身份验证传递
  • HTTP 方法:POST

然后是困难的部分:设置请求模板。我希望所有“订阅”请求都使用此模板,我发现这样做的唯一方法是将模板选择表达式设置为与路由选择表达式相同:$request.body.action,并将模板键设置为“订阅” ”。

它最终是对 API 应用此模板必须执行的相同内容的双重测试 - 如果有人有更好的方法来做到这一点,请发表评论。

然后最后一步是输入它作为“订阅”的“生成模板”:

{"connectionId": "$context.connectionId", "body": $input.body}
Run Code Online (Sandbox Code Playgroud)

请注意,在我的情况下,我的主体是 json 并且 $input.body 不在引号中 - 主体 json 被模板扩展。我想如果正文只是一个字符串,那么模板将是

{"connectionId": "$context.connectionId", "body": "$input.body"}
Run Code Online (Sandbox Code Playgroud)

但是路由永远不会到达这里,因为路由需要 body 来包含 json 中的动作键。