聊天/系统通讯应用程序(Nodejs + RabbitMQ)

所以我现在有一个运行NodeJS的聊天系统,通过兔子传递消息,每个连接的用户有自己的唯一队列订阅,只有听消息(只有他们)。 后端也可以使用这个聊天pipe道来传递其他系统消息,如通知/好友请求和其他用户事件驱动的信息。

目前,即使消息的有效载荷相同,比如说1000个用户,后端也必须循环发布每个消息1个用户。 我想摆脱这一点,并能够发送相同的消息给多个不同的用户,但不是每个连接的用户。

(例如:通知某些用户他们的朋友已经联机)。

我考虑实现一个兔子队列系统,在这个系统中,所有的消息被汇集到同一个队列中,而不是兔子发送所有的用户队列,节点接收这些消息,并通过套接字连接(向谁在线)发送消息给适当的用户。

build议 – 基础设施

这样后端不需要为100和1000的用户循环,并且可以发送包含这个消息应该去往的所有用户的单个有效载荷。 我打算将nodejs服务器集中在一起。

我也想知道,因为从来没有做过这样的生产环境,我需要跟踪每个socketID。

到目前为止,我已经发现了潜在的缺陷:

  • 由于1000条消息可以堆积在一个队列中,因此速度较慢。
  • 手动存储套接字ID以手动传送给用户。
  • 将路由卸载到NodeJS而不是RabbitMQ

有没有人做过这样的事情? 如果是这样,你有什么build议。 使用用户唯一队列进行扩展还是比较好?或者将所有用户的所有分组消息汇集到较小(但较大的队列)的队列中。

作为一般规则,每个用户排队是一个反模式。 这有一些有效的用途,但我从来没有见过这是一个聊天应用程序的好主意(尽pipe所有的演示使用这个例子)

RabbitMQ可以成为促进系统之间消息传递的强大工具, 但不应该用来将消息推送给用户 。

我考虑实现一个兔子队列系统,在这个系统中,所有的消息被汇集到同一个队列中,而不是兔子发送所有的用户队列,节点接收这些消息,并通过套接字连接(向谁在线)发送消息给适当的用户。

这是正确的方向,但你必须记住,RabbitMQ不是一个数据库(请参阅前面的链接,再次)。

您不能随机查找正在排队的特定消息,然后将其留在那里。 他们是先进先出。

在一个聊天应用程序中,我将有rabbitmq处理您的系统之间的消息传递,但不涉及到交付给用户。

你使用networking套接字的想法将成为你想要为之奋斗的方向。 无论是,还是服务器发送事件 。

如果你需要消息的持久性(历史,search,上次查看的位置等),那么使用一个数据库。 保留用户离开时间的时间标记或其他标记,并从该位置开始向他们推送消息。

你担心跟踪套接字的用户肯定是要考虑的事情。

如果有多个节点服务器实例运行不同用户连接的套接字,则需要知道哪些用户连接到哪个节点服务器。

对于rabbitmq来说,这可能是一个很好的用例 – 但不是以每用户队列的方式。 而是在每个用户的绑定中。 您可以让每个节点服务器创build一个队列,以接收来自发布消息的交换机的消息。 那么节点服务器将根据login到特定节点服务器的用户标识在交换和队列之间创build一个绑定

尽pipe如此,这可能会导致rmq中大量的绑定。

您可能需要一个更智能的方法来跟踪哪个服务器拥有哪些用户连接,或者完全忽略这些服务器,并将每条消息广播到每个节点服务器。 在这种情况下,每个服务器将基于消息应该传递给谁的方式通过websocket发布事件。

如果你使用的是足够聪明的websocket库,它只会将消息发送给需要它的人。 socket.io做到了这一点,我知道,我相信其他websocket库也是这样聪明的。

我可能没有给你一个具体的答案,我相信你有更多的上下文要考虑。 但希望这会让你走上正确的道路。