如何使用Websocket构建可扩展的实时聊天消息?

问题描述 投票:-1回答:1

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

当前,我们正在使用socket.io和socket.io-redis,其中每个websocket都使用其用户ID加入一个会议室,然后将它们应收到的每条消息发送到该会议室。此设计的问题在于,我们正在达到Redis Pubsub的极限,而Socket.io的扩展性不好(socket.io向所有检查用户是否连接的节点发送消息,这是不可行的。) >

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

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

我正在尝试通过25K +并发连接在视频游戏的用户之间建立实时(私人)聊天。当前,我们运行32个节点,用户可以在其中通过负载均衡器进行连接。我是问题...

node.js sockets redis rabbitmq
1个回答
0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.