如何确保IM 不丢消息是个相对复杂的话题,从客户端发送数据到服务器,再从服务器抵达目标客户端,最终在 UI 成功展示,其间涉及的环节很多,这里只取其中一环「接收端如何确保消息不丢失」来探讨,粗略聊下我接触过的两种设计思路。

说到可靠抵达,第一反应会联想到TCP 的 reliability。数据可靠抵达是个通用性的问题,无论是网络二进制流数据,还是上层的业务数据,都有可靠性保障问题,TCP 作为网络基础设施协议,其可靠性设计的可靠性是毋庸置疑的,我们就从 TCP 的可靠性说起。
在TCP 这一层,所有 Sender 发送的数据,每一个 byte 都有标号(Sequence Number),每个 byte 在抵达接收端之后都会被接收端返回一个确认信息(Ack Number), 二者关系为 Ack = Seq + 1。简单来说,如果 Sender 发送一个 Seq = 1,长度为 100 bytes 的包,那么 receiver 会返回一个 Ack = 101 的包,如果 Sender 收到了这个Ack 包,说明数据确实被 Receiver 收到了,否则 Sender 会采取某种策略重发上面的包。
数据可靠抵达网络层之后,还需要一层层往上移交处理,可能的处理有:安全性校验,binary 解析,model 创建,写 db,存入 cache,UI 展示,以及一些 edge cases(断网,用户 logout,disk full,OOM,crash,关机。。) 等等,项目的 feature 越多,网络层往上的处理出错的可能性就越大。
举个最简单的场景为例子:消息可靠抵达网络层之后,写db 之前 App crash(不稀奇,是 App 都会 crash),虽然数据在网络层可靠抵达了,但没存进 db,下次用户打开 App 消息自然就丢失了,如果不在业务层再增加可靠性保障,网络层面不会重发,那么意味着这条消息对于 Receiver 永远丢失

本文探讨了移动端即时通讯IM确保消息不丢失的方法,从TCP的可靠性机制出发,分析了应用层如何通过Ack机制和Seq ID连续性检查来增强消息的可靠性,同时讨论了数据正确抵达和持久化的意义,以及工程上对100%可靠性的理解。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



