node.js - 如何使用 Websocket 构建可扩展的实时聊天消息传递?

标签 node.js sockets redis rabbitmq

我正在尝试在具有 25K 以上并发连接的视频游戏用户之间建立实时(私有(private))聊天。我们目前运行 32 个 Node ,用户可以通过负载均衡器进行连接。我要解决的问题是如何将消息路由到每个用户?

目前,我们使用的是socket.io 和socket.io-redis,其中每个websocket 使用其用户ID 加入一个房间,并且我们将它们应该接收的每条消息发送到该房间。这种设计的问题在于,我们已经达到了 Redis Pubsub 的限制,而 Socket.io 的扩展性不佳(socket.io 向所有检查用户是否已连接的 Node 发出消息,这是不可行的)。

我们当前的堆栈由 Postgres、Redis 和 RabbitMQ 组成。我对这个问题思考了很多,并提出了 3 种不同的解决方案:

  • 使用 RabbitMQ 路由所有消息。当用户连接时,我们使用用户 ID 创建一个扇出类型的交换,并为每个 websocket 连接创建一个队列(我们必须处理每个用户的多个连接)。当我们想要发送给该用户时,我们只需发布到该交易所即可。这种方法的问题是我们必须创建很多队列,而且我听说这可能不是很有效。
  • 为 RabbitMQ 中的每个 Node 创建一个队列。当用户连接时,我们将 Node 和套接字 ID 保存在 Redis Set 中,以便当我们必须向该特定用户发送消息时,我们首先获取 Node 列表,发送到每个 Node 队列,然后处理路由到应用程序中的特定客户端。该方法的问题在于,在 Node 发生故障的情况下,我们可能会存储用户已连接,但事实并非如此。为了解决这个问题,我们需要使用户的 Redis 条目过期,但这并不是一个完美的解决方案。另外,如果我们以后想要实现群聊,就意味着我们必须在 Rabbit 中发送重复的消息,这并不理想。
  • 全力使用 Firebase 云消息传递。我们有一个移动应用程序,我们计划在用户未连接时使用它来推送通知,但即使用户已连接,它也适合吗?

您认为什么最适合我们的用例?你还有什么别的想法吗?

最佳答案

我找到了一个更好的解决方案:为每个用户创建一个绑定(bind),但在每个 Node 上仅使用一个队列,然后我们将每条消息路由到每个用户。

关于node.js - 如何使用 Websocket 构建可扩展的实时聊天消息传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61405784/

相关文章:

javascript - 无法 "npm install @tensorflow/tfjs-node"

node.js - Sequelize JSON字段只更新一个字段

linux - Socket Select() 工作正常,但 Poll() 工作不正常

java - 如何为 Spring Boot 中 SolrHealthIndicator 使用的 SolrClient 设置连接超时和 soTimeout?

caching - 执行 SET {Key} 超时,inst : 0, mgr : Inactive, 队列 : 2, qu=1, qs=1, qc=0, wr=1/1, in=0/0

javascript - Node 6.2/Mocha 2.4.5 : syntax errors on string template and default parameters

node.js - 为什么这个 if/else 在 ejs 中不起作用?

c++ - 如何通过 usb Lacewing::Client 接收数据?

node.js - Redis 键空间事件未触发

Laravel-echo-server docker 化问题