首页 > 解决方案 > 使用 Socket.io、RabbitMQ 和 Nodejs 处理多个聊天和通知客户端

问题描述

我正在构建一个社交媒体应用程序,周围会有很多人使用它。该应用程序还将具有聊天功能和实时通知功能。我构建聊天应用程序的过程如下:

选项 1:我已经使用 socket.io 构建了相同类型的应用程序,并在一个数组中管理所有用户的唯一套接字令牌,因为用户数量非常少。在这里,每当用户退出套​​接字时,我都会将它们从数组中删除。在发送任何聊天消息或触发任何通知时,我曾经从数组中搜索这些接收者(用户)的令牌并根据它们各自的套接字令牌发出它。

选项 2:我构建的另一个具有类似聊天功能的应用程序已使用 redis 构建,以根据用户的 id(键值对)存储令牌。在这里,redis 管理用户的令牌和列表。

但是现在当前的应用程序将在不久的将来拥有大量用户(可能 > 1M)。在那种情况下,我认为 redis 或任何手动管理的阵列将无法一次处理这些用户。使用上述选项时,我也有可能会丢失消息或通知。所以,我得出的结论是使用 RabbitMQ 通过 socket.io 来管理这一切。

我关心的是这样做的过程或最佳实践应该是什么。我得到了一些解决方案,其中我很困惑使用哪一个或者它是否是正确的实现方式。以下是我脑海中的流程列表:

  1. 当用户发送通知或聊天消息时创建 API。如果接收器连接到实时服务器,socket.io 将生成一个唯一的令牌。如果接收方和发送方都在线,则消息将由 socket.io 处理。如果消息没有送达怎么办?我什么时候应该将消息或通知保存在数据库中,因为没有确认收到它?

  2. 第二个想法是,假设如果接收者不在线,那么将使用其 id 生成一个新队列(RabbitMQ),并将消息推送到队列中。现在,当该接收者(用户)上线时,它应该在队列中查找是否存在给他的任何消息,这里将要求消费者获取消息并将其传递给相应的接收者。在这里,我需要将socket.io令牌保存在redis中吗?我应该使用 socket.io 和 RabbitMQ 进行实时通信吗?这是我有点困惑的地方。如何实际创建或管理它?我应该和 Firebase 一起处理这一切吗?

  3. 我想到的第三个解决方案是,首先将数据保存在数据库中,然后通过搜索存储在 redis 中的套接字令牌来查找接收者是否在线。如果找到则直接发出消息,如果没有则创建一个新队列(自动生成的 RabbitMQ 队列名称)并将信息保存在 redis 中。现在,每当用户上线时,消费者(用于消费或处理任务/消息的单独进程)将首先搜索其值(唯一队列名称)及其用户 ID 是否存在于 redis 服务器中。之后,消费者会根据在redis服务器中找到的队列名称查看消息队列,并最终通知用户。

我应该什么时候将消息保存在数据库中?我应该将消息保存在 DB 中,然后使用 Socket.io 通知或发出有效负载吗?如果接收者离线,我应该为 RabbitMQ 中的每个用户创建单独的队列吗?如何在用户再次上线时使用 RabbitMQ 通知用户未读消息?

我是在正确的道路上还是完全错误的过程。请通过解决方案提出您宝贵的反馈意见。

标签: node.jsredissocket.iorabbitmqreal-time

解决方案


推荐阅读