IM 系统设计,关于服务端如何管理连接的 Clients 问题?

ZivSF
  • 522

RT,问题概况:

  • 想做一个类似聊天室的APP,属于没有太多经验正在探索中,看了一些文章没有读太懂,比如我觉得读扩散(Pull)模式适合我,但不懂里面说的发件箱和数据库的表是什么关系。
  • 数据库用的MongoDB,存储消息建了两个表send_message(主要储存消息内容)、 received_message(主要储存消息相关ID)
  • 用户建立连接会在URL带一个UserId,因为WebSocket.Server服务端使用的是ws,所以最终可以拿到带有UserIdclients列表,有多少个建立连接就有多少个client。
  • 现在卤煮不知道一个群成员发出消息后,服务端监听到消息要推给哪些client,是否可以和redis结合实现(不过也有几种设想)

    1. 消息中附带群成员ID,再去clients过滤出频道中的client
    2. 打开chatroom时发送请求告诉服务端群ID,同样再去clients过滤出频道中的client

为了描述问题,作为制图小白还是画了“流程图”?

在线编辑

回复
阅读 735
1 个回答
✓ 已被采纳

加一个消息队列,每个房间登记为一个 topic,登录的 client 订阅他加入的所有房间的 topic 。发送消息时往 topic 推一个广播。

client 监听到消息队列的新事件的时候,再进入 onMessage 流程下发给客户端。

// 伪代码

onSend(function(msg){
  save(msg); // 持久化消息
  if (msg.type == GroupMessage) {
    exchange.publish(`topic-${msg.room_id}`, msg);
  }
})

exchange.subscribe('topic-room-id', queue, function(msg) {
  client.onMessage(msg)
})

该方案的客户端抽象模型:

image.png

架构示意图

image.png

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏