AWS API Gateway Web Socket Api - 向所有连接的客户端广播消息

GCS*_*SDC 8 javascript websocket aws-sdk aws-lambda aws-api-gateway

我已经使用 API Gateway 创建了一个 Web Socket Api,并且能够将客户端连接到它。

此外,我可以通过指定它ConnectionId并使用以下代码将消息发送到连接的客户端:

const AWS = require('aws-sdk');
let apiGatewayManagementApi = new AWS.ApiGatewayManagementApi({
  apiVersion: '2018-11-29',
  endpoint: 'https://XXXXXXXXX.execute-api.sa-east-1.amazonaws.com/dev/',
  region: 'sa-east-1'
});
const params = {
  ConnectionId: 'YYYYYYYYYYYYY',
  Data: 'test'
};
apiGatewayManagementApi.postToConnection(params, function (err, data) {
  if (err) {
    console.log(err, err.stack); // an error occurred
  } else {
    console.log(data);           // successful response
  }
});
Run Code Online (Sandbox Code Playgroud)

问题是我不需要区分客户端,所以我不想跟踪每个客户端的 ConnectionId,但是如果我在发送消息时删除它,我会收到以下错误: Missing required key 'ConnectionId' in params

有没有办法向所有连接的客户端发送消息(不指定任何 ConnectionId)?

Dan*_*one 7

不幸的是,您必须指定 ConnectionId。我见过的一种模式是在$connect事件上将连接信息持久化到 DynamoDB ;那么你可以做这样的事情:

const connections = await getAllConnections();
const promises = connections.map(c => apiGwMgmtApi.postToConnection({ ConnectionId: c.connectionId, Data: 'test' }).promise());
await Promise.all(promises);
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的回答!我已经在许多示例中看​​到了这种模式,但仍然希望有一种方法可以在不跟踪个人 ID 的情况下做到这一点。 (4认同)
  • 这种方法有一个问题,假设我们有 10K 客户端,这意味着我们调用 AWS api 10k 次,这是完全低效的。为了避免这个问题,在创建您自己的自定义套接字服务器时,有一个选项可以创建通道,并且无论加入该通道,他们都只需一次调用即可同时接收消息。我想知道AWS API Gateway是否也提供这个解决方案。 (3认同)
  • 同意 - 2022 年 API 网关不支持通道广播的概念,这太疯狂了。如果这个问题得到解决,很多技术堆栈都会转向该服务。或者,您可以做一些愚蠢的事情,例如在 API Gateway 上运行一半堆栈(用于 1:1 通信,而另一半堆栈在另一个广播解决方案上运行) - 这将需要来自客户端的多个 WS 连接,这让我很生气。 (3认同)