AWS API Gateway Websockets-connectionID在哪里?

时间:2019-01-10 17:25:17

标签: amazon-web-services websocket aws-api-gateway api-gateway

我正在$ connect路由上使用自定义授权者设置AWS API Gateway Websocket,如此处所述:

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

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

8 个答案:

答案 0 :(得分:3)

这里的问题是使用HTTP作为集成类型时-即在调用一个或多个API GW路由($ connect / $ disconnect / $ invoke)时,命中了http端点。我们发现我们无法代理请求(这意味着我们将丢失包括auth在内的原始标头),但是如果我们需要连接ID,则必须指定一个Request Template并使用类似以下内容:

{“ connectionId”:“ $ context.connectionId”,“ body”:“ $ input.body”}

答案 1 :(得分:3)

要解决此问题,请转到您的 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'

2- 之后不要忘记部署,否则将无法运行

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

答案 2 :(得分:1)

感谢大家尝试代表AWS进行文档编制。可惜的是AWS做得不好。

要使用VPC Link将数据从AWS Websocket API网关发送到您的集成服务,请执行以下操作:

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

  2. 保存

  3. 设置请求模板,如下图所示: Request Template Set Up of AWS Websocket API Gateway

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

  5. 保存

  6. 单击右上方的添加集成响应

  7. 按如下图所示设置集成响应Integration Response Setup

8。希望它会起作用。如果不是,请通过测试找出答案,然后在此处为其他人输入答案。因为AWS不会打扰提供好的文档。谢谢。

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

答案 3 :(得分:0)

该问题未指定使用哪种类型的后端。适用于AWS API Gateway的AWS文档适用于lambda函数-我找不到将connectionId传递到我的http后端的任何帮助。

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

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

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

  • 集成请求类型:HTTP

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

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

最终要对API应用此模板必须执行的相同内容进行两次测试-如果有人有更好的方法,请发表评论。

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

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

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

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

但是由于路由需要正文将动作键包含在json中,因此路由将永远无法到达此处。

答案 4 :(得分:0)

非常感谢Francois Stark,非常有帮助。

通过我自己的实验,我发现您可以避免使用$ default路由和以下格式来匹配$ request.body.action的特定值:

  • 模板选择表达式:\ $ default <-表示斜杠很重要
  • 模板密钥:\ $ default <-再次是斜杠
  • 生成模板
{"connectionId": "$context.connectionId", "body": $input.body}

使用此配置,您的HTTP端点应该使用一条路由在所有“操作”值中将connectionID作为正文数据获取。

此外,要获取$connect$disconnect路由中的connectionID,请求模板的格式是相同的,但是由于这些事件中没有正文数据,因此可以省略正文:

  • 模板选择表达式:\ $ default <-表示斜杠很重要
  • 模板密钥:\ $ default <-再次是斜杠
  • 生成模板
{"connectionId": "$context.connectionId"}

使用此配置,您的HTTP端点应该在$ connect和$ disconnect事件中将connectionID作为正文数据获取。

答案 5 :(得分:0)

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

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

可以在模板here中找到有关模板表达式中可用变量的文档。

(请注意,尽管$request在模板 Selection 表达式中是有效变量,但在模板本身中不是有效变量。请在此处使用$input。)

答案 6 :(得分:0)

您可以从event.requestContext获取connectionId。

exports.handler = async (event) => {
const data = event['body'];
const connectionId = event['requestContext']['connectionId'];};

答案 7 :(得分:-1)

您可以从上下文变量获取connectionId。请参阅以下有关WebSocket API可用变量的信息: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-mapping-template-reference.html

在Lambda函数中,您可以通过event.requestContext访问上下文变量。