我正在$ connect路由上设置带有自定义授权器的AWS API网关Websockets,如下所述:
我的问题是 - 如何获取connectionID,即我可以用来稍后广播到该连接客户端的标识符?
这里的问题是当使用HTTP作为集成类型时 - 即在调用一个或多个API GW路由时触发http端点($ connect / $ disconnect / $ invoke)。我们发现我们无法代理请求(意味着我们丢失了原始标头,包括auth),但如果我们需要连接ID,我们必须指定一个请求模板并使用如下内容:
{“connectionId”:“$ context.connectionId”,“body”:“$ input.body”}
该问题未指定使用何种类型的后端。 AWS API Gateway的AWS文档面向lambda函数 - 我找不到任何帮助将connectionId连接到我的http后端。
尝试Big Endian的答案,我发现了一些问题 - 我的cakephp后端不会解码引用的json体。我找到了解决方案,但实现他的答案需要许多其他步骤,所以这里是:
我创建了一个关闭HTTP代理的路由密钥,并按如下方式设置了一个请求模板(也是非常稀疏的文档):
然后是困难的部分:设置请求模板。我希望所有“订阅”请求都使用此模板,我发现这样做的唯一方法是将模板选择表达式设置为与路径选择表达式相同:$ request.body.action,并将模板键设置为“subscribe” ”。
它最终是对API应用此模板必须执行的相同内容的双重测试 - 如果有人有更好的方法,请发表评论。
然后最后一步是将其作为“订阅”的“生成模板”输入:
{"connectionId": "$context.connectionId", "body": $input.body}
请注意,在我的情况下,我的身体是json而$ input.body不在引号中 - 身体json被模板扩展。我想如果身体只是一个字符串,那么模板就是
{"connectionId": "$context.connectionId", "body": "$input.body"}
但是路由将永远不会到达此处,因为路由需要正文包含json中的操作键。
非常感谢Francois Stark,非常乐于助人。
通过我自己的实验,我发现你可以避免使用$ default路由和以下格式匹配$ request.body.action的特定值:
{"connectionId": "$context.connectionId", "body": $input.body}
使用此配置,您的HTTP端点应使用单个路由在所有“action”值中获取connectionID作为正文数据。
另外,为了在$connect
和$disconnect
路由中获取connectionID,请求模板的格式是相同的,但由于这些事件中没有正文数据,因此可以省略正文:
{"connectionId": "$context.connectionId"}
使用此配置,您的HTTP端点应该在$ connect和$ disconnect事件中获取connectionID作为正文数据。
您可以从上下文变量获取connectionId。有关WebSocket API的可用变量,请参阅此内容:https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-mapping-template-reference.html
在Lambda函数中,您可以通过event.requestContext访问上下文变量。