IM——为你的App,加上实时通信功能

如果为原有的业务系统增加实时消息模块,在不需要重建账号体系的前提下,整体上大概包括几块内容:

消息存储

一般来说,大部分即时消息系统为了便于查看历史消息或者用于暂存离线消息,都需要对消息进行服务端存储,因此,我们先来看一下,这些互动过程产生的消息在服务端该怎么存储或者暂存。

消息索引和消息内容

这里,以点对点消息的存储为例:

点对点消息的参与方有两个:发送方和接收方。收发双发的历史消息都是相互独立的。互相独立的意思就是:假设发送方删除了某一条消息,接收方仍然可以获取到这条消息。

所以,从库表的设计上分析,这里需要索引表中收发双方各自有一条自己的索引记录:一条是消息发送方的发件箱索引,另一条是消息接收方的收件箱索引。

由于收发双方看到的消息内容实际都是一致的,因此还需要一个独立的消息内容表。

联系人列表

有了消息和索引后,如之前描述的,一般IM系统还需要一个最近联系人列表,来让互动双方快速查找需要聊天的对象,联系人列表一般还会携带两人最近一条聊天消息用于展示。

这里你需要理解的是,和消息索引表的存储逻辑相比,联系人列表在存储上有以下区别

1.联系人列表只更新存储收发双方的最新一条消息,不存储两人所有的历史消息。

2.消息索引表的使用场景一般用于查询收发双方的历史聊天记录,是聊天会话维度;而联系人表的使用场景用于查询某一个人最近的所有联系人,是用户全局维度。

还是刚才那个例子,张三给李四发完消息后,除了在内容表和索引表插入记录,还会更新各自的最近联系人表,这里需要分别更新张三的最近联系人表和李四的最近联系人表。

比如更新张三的最近联系人表,如果和李四之前没有聊天记录,那么新插入一条联系人记录。联系人的对方UID为李四的UID,和这个联系人最新的一条消息ID是1001、

如果张三和李四之前已经有聊天记录,那么只需要更新张三和李四的最新的一条聊天消息ID为1001,同样的办法再更新一次李四的联系人列表。

消息收发通道

接下来我们需要考虑的是:如何将消息发出去,以及怎么把消息投递给接收方。这里逻辑上涉及了两条通道:一条是消息发送通道,一条是消息接收通道。

消息发送通道

1.IM服务端提供一个HTTP接口,客户端需要发送消息时,调用这个接口把消息发送给服务器

2、客户端和IM服务端维护一个TCP长连接,客户端有消息发送时,会以私有协议来封装这条要发送的消息,然后通过这个TCP长连接把消息发送给IM服务端

所以发送通道的实现相对比较简单,重点在于:IM服务端提供消息发送的API,发送方可以通过任意方式调用到这个API,把消息发出去即可。

消息接收通道

对于我们最常见的非P2P模式的IM系统来说,由于有一条消息要投递给某个接收方这个事件,接收方并没有办法能实时知道,只有IM服务端收到发送方发出的消息时能实时感知到,因此消息投递这个动作一般都是IM服务端触发的。

IM服务端的网关服务和消息接收方设备之间维护一条TCP长连接(或者websocket长连接),借助TCP的全双工能力,也就是能够同时接收与发送数据的能力。当有消息需要投递时,通过长连接实时把消息从IM服务端推送给接收方。

对于接收方不在线(比如网络不通,APP没打开等)情况,还可以通过第三方手机操作系统级别的辅助通道,把这条消息通过手机通知栏的方式投递下去。

当然这些第三方操作系统级别的辅助通道也存在一定问题,因此大部分情况下也只是作为一个辅助手段来提升消息的实时触达的能力,这个后续再介绍。

因此,对于消息接收通道,重点在于需要在IM服务端和接收方之间,维护一个可靠的长连接,什么叫可靠的长连接呢?

1.IM服务端和接收方能较为精确地感知这个长连接的可用性,当由于网络原因连接被中断时,能快速感知并进行重连等恢复性操作。

2.可靠性的另一层含义是:通过这个长连接投递的消息不能出现丢失的情况,否则会比较影响用户体验。后面展开讲

消息未读数

未读消息涉及了两个概念:一是我有多少条未读消息,二是我和某个联系人有多少条未读消息。

因此,我们在消息未读数的实现上,一般需要针对用户维度有一个总未读数的计数,针对某一个具体用户需要有一个会话维度的会话未读的计数。

这两个消息未读数变更的场景是下面这样的:

1、张三给李四发送一条消息,IM服务端接收到这条消息后,给李四的总未读数+1,给李四和张三的会话未读数也+1

2.李四看到有一条未读消息后,打开App,查看和张三的聊天页,这时会执行未读变更,将李四和张三的会话未读-1,将李四的总未读-1

这个具体的未读数存储可以是在IM服务端(如QQ,微博),也可以是在接收方的本地端上存储(微信),一般来说,需要支持消息的多终端漫游的应用需要在IM服务端进行未读存储,不需要支持可以选择在本地存储即可。

发布了43 篇原创文章 · 获赞 37 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_28119741/article/details/103836961
今日推荐