为什么我的API Gateway WebSocket不发送配置了自定义域名的响应?

时间:2019-04-19 03:36:04

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

我已使用API​​网关配置了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按照these instructions设置自定义区域域名时,我可以连接,但无法在客户端之间发送消息。

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

非常清楚,以下连接命令正确触发了我的Lambda函数,并使用AWS生成的URL和我自己的Route 53连接了我的客户端。

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

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

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

2 个答案:

答案 0 :(得分:0)

我们也遇到了同样的问题,但是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='...'
)

答案 1 :(得分:0)

这可能为时已晚。 这是因为使用postToConnection时,aws-sdk(AWS.ApiGatewayManagementApi)尝试仅使用其内部资源(在本例中为AWS生成的URL)来解析端点。 AWS开发工具包不了解外部资源(在本例中为您的自定义域)。因此,它适用于AWS生成的URL,而不适用于您的自定义URL。 如果要在后面的代码中处理此问题,则可能需要创建一个字典,将您的自定义URL映射到AWS生成的URL。或者,创建一个网络套接字客户端(非aws-skd)并传递自定义URL。 我个人还没有使用使用网络套接字客户端的第二种方法,但是我相信它应该可以工作。