【问题标题】:Return the connection ID when connecting to AWS API Gateway websocket连接 AWS API Gateway websocket 时返回连接 ID
【发布时间】:2021-12-14 14:52:15
【问题描述】:

我正在使用 AWS Cloud Formation,并努力了解 API Gateway 如何为 Websocket 工作。

我希望$connect 路由响应 OK 和 AWS API Gateway 分配的连接 ID。 所以例如在做的时候

wscat -c wss://my-custom-api-gateway-ws.com

我希望得到

Connected (press CTRL+C to quit)

以及诸如

之类的消息
< {"message": "Connected". "connectionId": "foo"}

或类似的。但我一直得到一个

wscat -c wss://my-custom-api-gateway-ws.com
error: Unexpected server response: 500

这是我尝试过的

  wsApiGateway:
    Type: AWS::ApiGatewayV2::Api
    Properties:
      Name: !Sub ${prefix}-ws-gateway
      Description: Api Gateway for Websockets
      ProtocolType: WEBSOCKET
      RouteSelectionExpression: $request.body.action
      DisableExecuteApiEndpoint: true

  wsConnectRoute:
    Type: AWS::ApiGatewayV2::Route
    DependsOn:
      - wsConnectIntegration
    Properties:
      ApiId: !Ref wsApiGateway
      RouteKey: $connect
      AuthorizationType: NONE
      OperationName: ConnectRoute
      RouteResponseSelectionExpression: $default
      Target: !Join
        - /
        - - integrations
          - !Ref wsConnectIntegration

  wsConnectIntegration:
    Type: AWS::ApiGatewayV2::Integration
    Properties:
      ApiId: !Ref wsApiGateway
      Description: Websocket $connect integration
      IntegrationType: MOCK
      RequestTemplates:
        application/json: "{\"statusCode\": 200, \"connectionId\": \"$context.connectionId\", \"message\": \"Success\"}"
      PayloadFormatVersion: 1.0

  wsApiStage:
    Type: AWS::ApiGatewayV2::Stage
    DependsOn:
      - wsConnectRoute
    Properties:
      StageName: production
      Description: Autodeploy in production
      AutoDeploy: true
      ApiId: !Ref wsApiGateway
      AccessLogSettings:
        DestinationArn: !GetAtt wsApiGatewayLogGroup.Arn
        Format: '{"requestTime":"$context.requestTime","requestId":"$context.requestId","connectionId":"$context.connectionId","domainName":"$context.domainName","stage":"$context.stage","httpMethod":"$context.httpMethod","path":"$context.path","routeKey":"$context.routeKey","status":$context.status,"responseLatency":$context.responseLatency, "responseLength":$context.responseLength, "integrationError":$context.integration.error}'

如果我完全删除路由 $connect,我可以连接但它不会返回任何消息

wscat -c wss://my-custom-api-gateway-ws.com
Connected (press CTRL+C to quit)

如果我通过 websocket 发送任何内容,我会收到一个包含连接 ID 的自动响应错误(我可以将其用作解决方法)。但我想在连接时获取该连接 ID,而不是在强制出错时获取。

wscat -c wss://my-custom-api-gateway-ws.com
Connected (press CTRL+C to quit)
> this is a silly message
< {"message": "Forbidden", "connectionId":"H-SaJeT8oECIUg=", "requestId":"H-SbUEHSoEF3JQ="}

我的理解是,我应该能够让它与 MOCK 集成类型一起使用,因为我不需要集成 http 服务或类似服务,并且 API 网关应该具有响应所需的所有内容。

有人做过类似的事情吗?


更新 1 我已经手动(尚未形成云)按照Setup a basic WebSocket mock in AWS ApiGateway 上的步骤添加 $connect 路由,使用 MOCK 集成,响应模板为

{"statusCode" : 200, "connectionId" : "$context.connectionId"}

但是连接时我看不到那个connectionId。

wscat -c wss://foo.execute-api.eu-west-1.amazonaws.com/production
Connected (press CTRL+C to quit)

另外,如果我添加了一个 $default 路由,那么一旦连接,我就可以向 websocket 发送消息并接收预期的 connectionId,但我似乎没有找到仅使用 $connect 路由接收 connectionId 的方法没有任何额外的路线。

【问题讨论】:

  • 如果添加响应模板会发生什么?
  • @noninertialframe 与 $connect 路由上的响应模板我看不出有什么区别。我可以连接,它说已连接,但它不会显示任何其他内容。请参阅更新 1

标签: websocket amazon-cloudformation aws-api-gateway


【解决方案1】:

您正在尝试将 HTTP 响应返回到 websocket;一旦转换为 websocket,就不能再使用 HTTP 响应了。

我只返回一个null。要将数据发送到客户端,请启动 Lambda 并使用 postToConnection API 函数通过 connectionId 推送数据。 (这是Javascript SDK的链接。)


编辑:

嗯。我在较新的代码中看到我确实从我的 Lambda 中返回 return { statusCode: 200 },但仅此而已。内容仍会通过 API 调用发出。

【讨论】:

猜你喜欢
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
  • 2015-10-23
  • 2019-09-11
  • 2022-10-24
  • 2018-11-19
  • 2019-09-20
  • 1970-01-01
相关资源
最近更新 更多