10

我已经使用 API Gateway 配置了一个 WebSocket API,并试图为其配置一个自定义域名。这是一个非常简单的 API,用于在连接的客户端之间发送消息,将连接 ID 存储在 DynamoDB 中。本质上,它类似于此处演示的示例:https ://aws.amazon.com/blogs/compute/announcing-websocket-apis-in-amazon-api-gateway/

使用 AWS 生成的 URL 即 wss://.execute-api.us-west-2.amazonaws.com/ 时一切正常。但是,当我按照AWS 的这些说明设置自定义区域域名时,我可以连接但无法在客户端之间发送消息。

我检查了我的 Lambda 函数的 Cloudwatch 日志,没有看到任何错误,并尝试使用我的 CloudFormation 模板启动一个全新的环境,但无济于事。

很清楚,以下连接命令会正确触发我的 Lambda 函数,并使用 AWS 生成的 URL 和我在 Route 53 中的 URL 连接我的客户端。

wscat -c wss://<endpoint> <payload>

以下命令向连接的客户端发送消息,使用 AWS 生成的 URL 但不是我自己的。

{ "message": "sendMessage", "toId": "193818", "data", "a random msg" }
4

2 回答 2

7

我们遇到了同样的问题,但是 api 返回了一个错误:

botocore.errorfactory.ForbiddenException: An error occurred (ForbiddenException) when calling the PostToConnection operation: Forbidden

我们最终手动构建了回调 url 以发送回响应:{api_id}.execute-api.{region}.amazonaws.com

您可以从传递给 lambda 函数的请求上下文中获取 api id。

我们使用的 python/boto3 代码:

stage = event['requestContext']['stage']
api_id = event['requestContext']['apiId']
region = 'us-east-1'

domain = f'{api_id}.execute-api.{region}.amazonaws.com'
client = boto3.client('apigatewaymanagementapi', endpoint_url=f'https://{domain}/{stage}')

client.post_to_connection(
    Data='...',
    ConnectionId='...'
)
于 2019-09-04T16:08:54.150 回答
0

答案可能有点晚了。这是因为在使用 postToConnection 时,aws-sdk (AWS.ApiGatewayManagementApi) 尝试仅使用其内部资源(在本例中为 AWS 生成的 URL)解析端点。AWS 开发工具包不知道外部资源(在这种情况下是您的自定义域)。因此,它适用于 AWS 生成的 URL,而不是您的自定义 URL。如果您想在后面的代码中处理这个问题,那么您可能需要创建一个字典,将您的自定义 URL 映射到 AWS 生成的 URL。作为替代方案,创建一个 web-socket 客户端(非 aws-skd)并传递您的自定义 URL。我没有亲自使用过使用 web-socket 客户端的第二种方法,但我相信它应该可以工作。

于 2019-09-23T20:33:56.387 回答