如何设计一个聊天软件(二)
创始人
2026-01-31 06:03:13
0

上篇文章我们从高阶设计角度聊了下聊天软件设计(链接)。这篇文章会详细介绍一下各具体模块。

服务发现

服务发现的主要职责是根据一些条件,比如说地理位置,服务器容量等等,来给客户端推荐最好的聊天服务器。Apache Zookeeper是主流的服务发现开源解决方案。它根据预设条件注册所有的可能聊天服务器并且为客户端选择最好的聊天服务器。

  1. 用户A尝试登陆到app

  2. 负载均衡发送登陆请求到API服务器

  3. 验证好用户后,服务发现为用户A找到最适合的聊天服务器。在这个例子中,选择了服务器2并将服务器信息返回给用户A

  4. 用户A通过websocket连接到服务器2

信息流

1对1聊天流

下图解释了当用户A发送信息给用户B发生了什么。

1. 用户A发送聊天信息给到聊天服务器1

2. 聊天服务器1从ID生成器中获取到了信息ID

3. 聊天服务器1发送信息到信息同步队列

4. 信息被存储在键值数据库中

5. a. 如果用户B在线,信息会被推送到用户B所连接的聊天服务器2

   b. 如果用户B离线,推送通知服务器会发送推送服务

6. 聊天服务器2发送信息到用户B。用户B和聊天服务器2之间会有持续的websocket连接

在多设备之间的信息同步

通常情况下用户有多台设备。

上图中,用户A有两台设别:一部手机会一台电脑。当用户A用手机登陆到聊天软件,那么手机端便与聊天服务器1建立了websocket连接。类似的,电脑端和聊天服务器1之间也有连接。

每台设备都会有一个变量叫cur_max_message_id,这个变量用于追踪设备上的最新message id。满足以下两个条件的信息可以被认为是新信息:

  • recipient id = 当前登陆 user id

  • 在键值存储中的message id大于cur_max_message_id

因为每台设备上有*cur_max_message_id*,所以同步是比较容易的因为每台设备可以据此从键值存储中获取最新的信息。

小组群聊流

对比起1对1聊天,群聊的逻辑会更复杂。

上图中解释了当用户A在群组聊天的时候发送信息会发生什么。设想群组里一共3个成员(用户A,用户B,用户C)。首先,User A发送的信息会被复制到每个群组成员的信息同步队列中。你可以认为信息同步队列相当于接收人的收信箱。这种设计选择适用于小群组群聊是因为:

  • 简化了信息同步流因为每个客户端只需要检查自己的收信箱是否有新信息

  • 当群组成员人数较小时,在每个收件人的收信箱存储备份的成本并不高

微信使用的是相似的策略,并且它限制群聊人数上限为500人。然而,对于有许多用户的群来说,为每个群组成员存储信息备份是不可接受的。

在线状态

在线状态指示器是许多聊天app的一个重要功能。通常,你可以在用户的头像或用户名旁看到一个绿点。

在高层设计中,存在服务器负债总额管理在线状态,并通过websocket与客户端通信,有以下几个流程会出发在线状态的变化

用户登陆

用户登陆流已经在“服务发现”部分解释过了。在websocket连接建立之后,用户A的在线状态和*last_active_at*时间戳会被存储在键值存储中。当用户登陆在线状态显示器会显示用户在线状态。

用户登出

以下是用户登出流。在键值存储中在线状态会被更改为离线状态。

用户断开连接

在真实的使用场景中,用户的网络可能并不稳定。当用户从互联网断开连接时,客户端与服务器之间的持久连接就会丢失。处理用户断开连接的一种简单方法时将用户标记为离线,并在连接重新建立时改变状态为在线。然而,这种方法有一个主要缺陷。用户频繁的在短时间内断开和重新连接互联网是很常见的。例如,当用户穿过隧道时,网络连接可能会断断续续。每次断开/重连时都更新在线状态会使得在线状态指示器变化太频繁,导致糟糕的用户体验。

我们引入心跳机制来解决这个问题。在线客户端定期向存在服务器发送心跳事件。如果存在服务器在一定时间内,比如说从客户端开始的x秒内,收到心跳时间,那么用户被认为是在线的。否则,就是离线的。

下图中,客户端每5秒发送心跳事件到服务器。当发送3次心跳事件后,客户端失联并且在x=30秒内并没有重新连接。那么在线状态会被更改为离线。

在线状态扩散

用户A的好友如何知道用户A的状态变化呢?下图解释了运行机制。在线显示服务器使用publish- subscribe模型,也就是说每个好友对中会维护一个通道。当用户A的在线状态改变的时候,会发送事件到三个通道中,通道A-B,A-C,A-D。这三个通道分别被用户B,C,D订阅。这样,他们便能获取到好友的状态变化。客户端和服务器之间的通信是通过实时的websocket。

上述设计对于小群组是比较高效的。例如,微信使用类似的策略因为它的群聊用户上限为500人。对于大型群组来说,通知所有成员在线状态的成本是很高而且也很耗时。假设一个群组有100000名成员,那么每个状态改变会生成100000次事件。为了解决这个瓶颈,一个可能的方案是只有当用户进入到群组或手动刷新好友列表的时候才会去获取好友在线状态。

相关内容

热门资讯

9... 音乐人非常关心的一个问题:有些人似乎不缺乏灵感。对于某些人来说,写一首歌=掉一把头发。如果我没有创作...
天... 点击上方蓝字关注我们,获取更多BIM及建工行业资讯资源简介:本次给大家分享的是天正建筑T20-软件教...
静... 最近因为疫情,城市实行了静默管理,打字聊天的机会多了。 以此来使用五笔字体输入法,简称五笔。 我小学...
夏... 每天发现新趋势——————火电站热效率水平提高10%以上研究| 黄勇 崔克佳 | 黄勇2015年锅炉...
多... IOS神器公众号推送改版,星标后准时接收推文免责声明    公众号中的所有“软件”、“图像”、“资源...
松... 荆州新闻网(记者彭军 通讯员陈越 陈俊龙)“GOIP”是一种用于网络通信的硬件设备。 支持手机卡接入...
软... 日常更新/限免安卓WiFi小部件 1.4.04 - 监控WiFi详细可拓浏览器 7.5.8.1 - ...
专... 新学期的首要任务就是检查你的课程表。 但每次要进入信息门户时,有时会因为人太多而无法显示页面。 即使...
二... 展开
如... 上篇文章我们从高阶设计角度聊了下聊天软件设计(链接)。这篇文章会详细介绍一下各具体模块。服务发现服务...
文... 文华财经期货指标公式博易大师软件指标期货趋势多空买卖提示指标点击下方文华指标公式大全公众号名片,关注...
自... 自动剪裁⭐删除:惊人的剪切网站日常生活中,我们时常会遇到需要剪切图片的情况:初级玩家打开图片秀跃跃欲...
电... 电脑PS软件哪款比较好? 生活在如此高科技的时代,不会Photoshop怎么办? 很多朋友都会通过一...
这... 这是软件行业的公司列表。 希望能为软件圈的朋友以及关注软件圈的朋友提供参考文档。下面欣赏一下~1、行...
光... 各位朋友大家好! 我是陶陶君~说到图像处理,很多人第一个想到的就是PS。 然而,并不是每个人都会使用...
《... #####我们日常使用Windows系统时,有些软件是可以开机启动的。 有些用户想知道如何设置。 本...
我... 事情是这样的,我想你今天一定是被小栗子刷到了,终于得到了小金。 身材矮小的高晓松在微博上晒出了一张自...
G... 点击上方蓝色“后端技术学校”关注并加“星”第一时间阅读最新文章阅读本文大约需要5分钟珍惜当下,因为每...
西... 戴女士13991626426微信a13391608909曹女士15529096602(微信同号)02...
碧... 碧桂园生态城·千月湾(东湖高新-华山)获得预售证书27号楼16层高层建筑启动建筑面积约77-92平方...