即时消息技术剖析与实战
袁武林
微博研发中心技术专家
24187 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 25 讲
即时消息技术剖析与实战
15
15
1.0x
00:00/00:00
登录|注册

09 | 分布式一致性:让你的消息支持多终端漫游

多条消息打包和压缩
持久化的最近联系人列表和索引表
获取增量消息和信令
客户端和服务端版本的差异
减少用户上线时离线消息的数据传输量
优化离线消息的下推
离线消息存储未命中时的补救
版本号机制
离线消息存储
设备维度的在线状态
问题与解决方案
多终端和服务端状态同步的机制
实现方式
消息多终端漫游
分布式一致性

该思维导图由 AI 生成,仅供参考

你好,我是袁武林。今天我们开始进入场景篇的部分,在这个部分中,我会介绍在几种典型的垂直业务场景下,IM 系统具体是如何实现的。
在即时消息的场景里,消息的多终端漫游是一个相对比较高级的功能,所谓的“多终端漫游”是指:用户在任意一个设备登录后,都能获取到历史的聊天记录。
这个功能对于有多个手机的用户来说是一个非常有用的功能,试想一下用户在交叉使用多个手机进行聊天后,如果不能在多个终端间自动同步所有的聊天记录,使用体验也不会太好。
但并不是所有的即时消息 App 都支持这个特性,比如微信虽然支持多端登录,但不知道出于什么考虑并不能在多端同步历史消息,这可能也是微信为数不多被诟病的一个小问题吧。
而 Telegram 和 QQ 却很好地支持了“多终端漫游”,使得用户在任意端登录都能获取到所有最近收发的消息。

如何实现多终端消息漫游

那接下来我们看一下,怎么才能让收发的消息能在多个终端漫游。要支持消息多终端漫游一般来说需要两个前置条件:一种是通过设备维度的在线状态来实现,一种是通过离线消息存储来实现。

设备维度的在线状态

对于在多个终端同时登录并在线的用户,可以让 IM 服务端在收到消息后推给接收方的多台设备,也推给发送方的其他登录设备。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了即时消息系统中实现多终端漫游的技术细节,着重介绍了在线状态维护、离线消息存储和多端消息同步机制。针对离线消息的下推采用消息打包和压缩方式,以优化用户上线体验。同时,文章还提到了发送方设备同步问题的解决方案。总的来说,本文对于即时消息系统开发和分布式一致性感兴趣的技术人员具有一定的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《即时消息技术剖析与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(39)

  • 最新
  • 精选
  • 王棕生
    如果用户的离线消息比较多,有没有办法来减少用户上线时离线消息的数据传输量? 答: 用户所有的离线消息对用户来说,并不都是关心和感兴趣的,用户可能只是看了与某个最近联系人的最近的几条消息后,之前的都不想看了,所以这个时候如果将之前的离线消息都拉到本地是非常浪费资源的。通常的做法是: 1 将用户的所有离线消息,按联系人进行分开; 2 用户登录后进入与联系人的聊天窗口时,首先加载与该联系人的最近的10条离线消息; 3 当用户用手滑动手机屏幕的时候,再分页拉取10条。

    作者回复: 是的,推拉结合是一种不错的折中方式。

    2019-09-16
    2
    16
  • 王棕生
    老师,对消息的终端漫游,我这边还有一个云消息的实现方案,望点评! 1 所有的消息,全部持久化存储; 2 用户在任意一个终端设备登陆后,通过用户的uid、联系人uid去服务端拉取云消息; 3 拉取云消息的时候,是按每条消息的时间戳倒序拉取,首次拉取可以取当前时间戳。

    作者回复: 整体上没啥大问题哈,首次拉取可以不带时间戳,默认服务端就获取最新的N条即可。 另外时间戳是服务端应用服务器生成的么?多服务器间的时钟差异能接受吗?也可以考虑搭建一套全局的“时间相关的序号生成器”来生成消息ID,使用消息ID作为拉取的cursor,这样时间生成上也相对稳定一些。

    2019-09-16
    2
    14
  • 离线消息什么情况下进行存储呢?当用户A给用户B发送一条消息,发现没有用户B的连接信息,这个时候才进行离线消息的存储吗,还是只要有消息发送给B都会进行离线消息的存储,因为这些消息对于用户B的其他设备来说属于离线消息?

    作者回复: 出于可靠性考虑,一般来说服务端接收到消息不管接收方是否在线都会先存到离线存储中,同步再进行消息在线推送,如果接收方不在线或者在线推送失败,等下次接收方再次上线时会从这个离线存储中获取消息进行补推。

    2019-09-17
    6
  • 分清云淡
    最后的发送方设备同步的问题,没太明白。怎么确定发送设备呢?服务端还有一份设备消息的关系表么?

    作者回复: 是的,对于支持多设备同时登陆的场景,用户上线建立长连时是以uid + 设备id 为维度来记录和连接的映射的,所以发消息时携带设备id,服务端就可以区分出具体是用户的哪个设备发送的,下推时就可以区别处理了。

    2019-12-03
    3
  • javaworker
    有几个问题没想明白,望老师帮解答下,谢谢 1.文中说如果离线消息存储容量超过限制,部分增量消息被淘汰掉了,会导致根据客户端最新版本号获取增量消息失败。 这个问题有些不明白,如果部分增量消息被淘汰,个人觉得也没关系吧,服务端每次把比客户端版本号大的消息都发给客户端就行了啊,怎么会失败呐? 2.文中说的离线消息表中该怎么存?比如A用户和B用户各有两个终端,但都只登陆了一个终端,这时A用户给B发送了一条消息,是按照A的userid存一条消息,按照B的userid也存一条一样的消息,A端上线拉取A的离线,B端上线拉取B的离线,也就是说A的离线消息有自己发出去的,也有别人发给A的消息,统一按照版本号存下来,A上线后都一起会拉走?

    作者回复: 第一个问题如果容量超限被淘汰掉仍然取大于版本号的消息下推的话可能会导致消息漏推。比如:客户端当前版本号是1,接下来的消息是2,3,4,假如2被淘汰,那么只会下推3和4,导致2漏推。 第二个问题,是的,离线消息按照用户维度来存储,发送方和接收方都会存,因为发送方也可能有多台设备。

    2019-09-24
    2
    3
  • K.Zhou
    微信不能多端同步消息是因为消息没存在服务端吧?

    作者回复: 这个可能是个结果不是个原因,可能微信产品的设计上就是不想支持多终端消息漫游,所以消息不需要长时间存储在服务端。

    2019-09-16
    4
    3
  • yangzi
    老师好,看了您的课程,有个问题:多终端消息同步和离线消息机制该如何搭配使用?这两个的功能类似。感觉离线消息更靠谱一些,因为它有ack,而多终端同步一旦客户端收到的消息不全,比如发送1、2、3,接收端收到1、3,拿3同步消息,同步也就会遗漏消息。

    作者回复: 其实这里讲的多终端消息同步就包括离线消息的同步,消1,2,3这种自增序号解决不了丢消息的问题,一种解决方案是在接收端维护起一个链表式结构,每条下推的消息都会携带上一条消息的版本和当前这条消息的版本(版本是用户维度,维护在服务端),接收端需要能够将这些版本都串联起来,否则就需要从断开的位置重新发起同步。

    2020-03-01
  • vearne
    延迟加载也是一个办法吧

    作者回复: 延迟加载能够一定程度缓解突发峰值流量,但对于持续高流量缓降作用有限。可以从提升写入能力角度去考虑,比如写合并。

    2019-11-11
  • GeekAmI
    多端漫游,感觉是为了解决一个问题,而引入很多问题的解决方案。 让不用手动端到端同步聊天记录,岂不是更好吗[Facepalm][Facepalm][Facepalm]

    作者回复: 多终端漫游目前也是有比较成熟的解决方案呀,技术上并不存在问题。

    2019-11-06
  • GeekAmI
    "但并不是所有的即时消息 App 都支持这个特性,比如微信虽然支持多端登录,但不知道出于什么考虑并不能在多端同步历史消息,这可能也是微信为数不多被诟病的一个小问题吧。" 1. 如果2台设备(mac和手机)都登录的情况下,消息会同步的; 2. 支持从一台设备上把历史聊天消息无损的同步到另一台设备。 我认为微信的方案即不复杂,也完美的解决了问题,很好啊 希望老师解答下,微信的这种方案缺陷是?不太明白

    作者回复: 1. mac和手机同时登陆能够同步离线消息这个特性应该上了没多久吧,目前也仅仅是同步一段时间的离线消息,并不是能完全同步所有消息的。 2. 支持一台设备同步到另一台的前提是需要人工干预,不是自动的,实际上是把一台设备的消息打包发送给另一台。 并不是说这种实现方式不好,看个人的需求程度。如果你希望能够随时随地通过任意终端都能看到所有的历史聊天,那微信目前的方案可能存在一定的问题。

    2019-11-06
    5
收起评论
显示
设置
留言
39
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部