即时通讯软件如何保证消息的不重复和不丢失

一、 文类型

im的客户端与服务器通过发送 文(也就是请求包)来完成消息的传递, 文分为三种,请求 文(request,后简称为为R),应答 文(acknowledge,后简称为A),通知 文(notify,后简称为N),这三种 文的解释如下:

三、上述消息投递流程出现的问题

从流程图中容易看到,发送方client-A收到msg:A后,只能说明im-server成功接收到了消息,并不能说明client-B接收到了消息。在若干场景下,可能出现msg:N包丢失,且发送方client-A完全不知道,例如:
1)服务器崩溃,msg:N包未发出
2) 络抖动,msg:N包被 络设备丢弃
3)client-B崩溃,msg:N包未接收
结论是悲观的:接收方client-B是否有收到msg:N,发送方client-A完全不可控,那怎么办呢/p>

四、应用层确认+im消息可靠投递的六个 文

upd是一种不可靠的传输层协议,tcp是一种可靠的传输层协议,tcp是如何做到可靠的案是:超时、重传、确认。
要想实现应用层的消息可靠投递,必须加入应用层的确认机制,即:要想让发送方client-A确保接收方client-B收到了消息,必须让接收方client-B给一个消息的确认,这个应用层的确认的流程,与消息的发送流程类似:

七、消息的重传存在什么问题

第五章提到过,msg:N 文,ack:N 文都有可能丢失:
1)msg:N 文丢失,说明client-B之前压根没有收到“你好” 文,超时与重传机制十分有效
2)ack:N 文丢失,说明client-B之前已经收到了“你好” 文(只是client-A不知道而已),超时与重传机制将导致client-B收到重复的消息,那怎么办呢
启示:
平时使用qq,或许大伙都有类似的体验,弹出一个对话框“因为 络原因,消息发送失败,是否要重发”,此时,有可能是对方没有收到消息(发送方 络不好,msg:N丢失),也可能已经收到了消息(接收方 络不好,反复重传后,ack:N依然丢失),出现这个提示时,大伙不妨和对端确认一下,看是哪种情况。

八、消息的去重

解决方法也很简单,由发送方client-A生成一个消息去重的msgid,保存在“等待ack队列”里,同一条消息使用相同的msgid来重传,供client-B去重,而不影响用户体验。

九、其他

1)上述设计理念,由客户端重传,可以保证服务端无状态性(架构设计基本准则)
2)如果client-B不在线,im-server保存了离线消息后,要伪造ack:N发送给client-A
3)离线消息的拉取,为了保证消息的可靠性,也需要有ack机制,但由于拉取离线消息不存在N 文,故实际情况要简单的多,即先发送offline:R 文拉取消息,收到offline:A后,再发送offlineack:R删除离线消息

十、总结

1)im系统是通过超时、重传、确认、去重的机制来保证消息的可靠投递,不丢不重
2)切记,一个“你好”的发送,包含上半场msg:R/A/N与下半场ack:R/A/N的6个 文

个人消息是一个1对1的ack,群消息就没有这么简单了,群消息存在一个扩散系数,如果大家感兴趣,下一次将和大家讨论im群消息的可靠投递。

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2018年5月1日
下一篇 2018年5月1日

相关推荐