http - 使用 HTTP 集成从 AWS Api Gateway 中的 websocket 中提取 websocket 连接 ID 和其他详细信息

标签 http websocket aws-api-gateway

我有一个 http 端点 https://websocketsample.free.beeceptor.com 以及 AWS 中用于 Websockets 的 API 网关,带有 $connect$disconnect$default 的路由,所有这些都与 HTTP 集成到一个POST https://websocketsample.free.beeceptor.com 以便我可以捕获 http 请求。

当我用 wscat 测试它时

wscat -c wss://e96ypxXXXX.execute-api.eu-west-3.amazonaws.com/production

我可以看到在 HTTP 服务器(在我的例子中是蜂感受器)接收到的 HTTP 请求。问题是 $connect 和 $disconnect 在 POST 请求中没有任何有效负载,只有 http header 。示例:

  • 当我 $connect 到 websocket 时,我得到
    Request body: empty
    Headers:
    {
      "content-length": "0",
      "sec-websocket-extensions": "permessage-deflate; client_max_window_bits",
      "sec-websocket-key": "pTR36OHKUSk8cqBix8vJXA==",
      "sec-websocket-version": "13",
      "x-amzn-trace-id": "Root=1-605322fb-1e2b058363326df80a61df18",
      "x-forwarded-for": "185.153.165.121",
      "x-forwarded-port": "443",
      "x-forwarded-proto": "https",
      "user-agent": "AmazonAPIGateway_e96ypxXXXX",
      "x-amzn-apigateway-api-id": "e96ypxXXXX"
    }
    
  • 当我向 websocket 发送任何消息时,例如 {"action":"action1"} 我得到
    Request body: {"action":"action1"}
    Headers:
    {
      "content-length": "20",
      "user-agent": "AmazonAPIGateway_e96ypxXXXX",
      "x-amzn-apigateway-api-id": "e96ypxXXXX",
      "content-type": "application/json; charset=UTF-8"
    }
    
  • 当我 $disconnect 我得到的 websocket
    Request body: empty
    Headers:
    {
      "content-length": "0",
      "x-api-key": "",
      "x-forwarded-for": "",
      "x-restapi": "",
      "user-agent": "AmazonAPIGateway_e96ypxXXXX",
      "x-amzn-apigateway-api-id": "e96ypxXXXX"
    }
    

如何获取连接 ID 以便我可以独立跟踪每个 websocket session ? 当我使用 lambda 对此进行测试时,请求有一个 requestContext,我可以在其中提取 connectionId 并使用 DynamoDb 来管理连接。 我不想使用 AWS Lambda,我已经有一个可以处理这个问题的 http 后端服务。但是 HTTP 集成似乎并没有提供太多信息。


更新1:这篇文章可能会解释一些原因https://docs.aws.amazon.com/apigateway/latest/developerguide/websocket-api-data-mapping.html 显然:

“AWS 管理控制台不支持 WebSocket API 的数据映射。您必须使用 AWS CLI、AWS CloudFormation 或软件开发工具包来配置数据映射。”

所以我可能需要在控制台外配置数据映射,并希望构建一个有意义的负载


更新 2:我根据 https://docs.aws.amazon.com/apigateway/latest/developerguide/websocket-api-data-mapping.html#websocket-mapping-request-parameters 添加了请求参数但没有运气

$ aws --profile diegosasw apigatewayv2 update-integration --integration-id 3lppdXX --api-id oe9jal8gXX --request-parameters 'integration.request.header.connectionId'='context.connectionId'
{
    "ConnectionType": "INTERNET",
    "IntegrationId": "3lppdXX",
    "IntegrationMethod": "POST",
    "IntegrationType": "HTTP_PROXY",
    "IntegrationUri": "https://websocketsample.free.beeceptor.com/connections",
    "PassthroughBehavior": "WHEN_NO_MATCH",
    "PayloadFormatVersion": "1.0",
    "RequestParameters": {
        "integration.request.header.connectionId": "context.connectionId"
    },
    "TimeoutInMillis": 29000
}

连接请求仍然没有转发到带有 http header 或任何地方的 connectionId 的 beeceptor,我不知道如何实现。

另外.. 我在创建 http 端点时发现了 API Gateway API Websocket 中的一个问题:Unable to use different HTTP verbs in API Gateway with API Websocket and HTTP integration

不是最直观的文档或用法。


解决方案:根据标记的答案,解决方案就像重新部署 API 一样简单。然后请求参数将被正确转发。

"Items": [
        {
            "ConnectionType": "INTERNET",
            "IntegrationId": "okmv0au",
            "IntegrationMethod": "POST",
            "IntegrationType": "HTTP_PROXY",
            "IntegrationUri": "https://awswebsocket.free.beeceptor.com",
            "PassthroughBehavior": "WHEN_NO_MATCH",
            "PayloadFormatVersion": "1.0",
            "RequestParameters": {
                "integration.request.header.domainName": "context.domainName",
                "integration.request.header.stage": "context.stage",
                "integration.request.header.connectionId": "context.connectionId",
                "integration.request.header.messageId": "context.messageId"
            },
            "TimeoutInMillis": 29000
        }
    ]

最佳答案

您很可能忘记部署 API(路由 -> 操作 -> 部署 API)。 WebSocket API 仍然使用没有自动部署的旧控制台。

当我尝试时,它会起作用

        {
            "ConnectionType": "INTERNET",
            "ContentHandlingStrategy": "CONVERT_TO_TEXT",
            "IntegrationId": "iasyqzb",
            "IntegrationMethod": "ANY",
            "IntegrationType": "HTTP_PROXY",
            "IntegrationUri": "[REDACTED]",
            "PassthroughBehavior": "WHEN_NO_MATCH",
            "PayloadFormatVersion": "1.0",
            "RequestParameters": {
                "integration.request.header.connectionId": "context.connectionId"
            },
            "TimeoutInMillis": 29000
        },

标题:

connectionid: dL53oem8IAMCK9g=
host: [REDACTED]
sec-websocket-key: dJleaOF55APY+0K6bPJWmg==
sec-websocket-version: 13
user-agent: AmazonAPIGateway_fhyhvnschc
x-amzn-apigateway-api-id: fhyhvnschc
x-amzn-trace-id: Self=1-6067d697-7dc1eea10d51468c3adbbc80;Root=1-6067d697-048e3deb132e05d50553a29e
x-forwarded-for: [REDACTED]

关于http - 使用 HTTP 集成从 AWS Api Gateway 中的 websocket 中提取 websocket 连接 ID 和其他详细信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66688751/

相关文章:

node.js - 在NestJs中使用Socket IO加入并发布到房间

nginx - 带有 nginx 的 Django channel 客户端没有收到消息

amazon-web-services - 如何通过cloudformation附加vpc链接以获取api网关中的方法

amazon-web-services - 使用 AWS Api Gateway 进行 Api 组合

amazon-web-services - AWS API Gateway HttpAPI SAM 自定义域名错误

javascript - 如果服务器响应 401/402 状态,Deferred.fail() 会被触发吗?

http - 为什么我们仍然使用 HTTP 而不是 WebSockets 来构建 Web 应用程序?

express - Apollo Server 作为 Nuxt 服务器中间件

ruby-on-rails - protect_from_forgery 不保护 PUT/DELETE 请求

performance - nodejs http 和 redis,只有 6000req/s