im即时通讯开发:群聊消息的已读未读功能

IM系统中,特别是在企业应用场景下,消息的已读未读状态是一个强需求。

功能看起来很酷,但用起来是一言难尽(上班族心里苦.... )。实际上,技术实现也并不容易。

那么,对于已读未读状态:

    1)如果是私聊:消息的阅读状态比较容易实现,在性能和存储上也不存在问题;

    2)如果是群聊:考虑到存储和处理性能,特别当处于一个云环境时,如何高效地处理群聊的已读未读状态是一个非常值得探讨的话题。

这里提到的“高效”含3个方面:

    1)存储空间;

    2)处理速度;

    3)传输字节数。

本文将从服务端的角度来探讨已读未读状态,在具体的技术实现上对于存储空间占用方面的思路差异。

已读未读状态交互流程

发送者发送的IM聊天消息,在接收者阅读消息后,是否要求阅读者通知已读,可能是由系统配置、组织配置、群组配置等决定,也可能由发送者根据业务需求决定。以下的讨论,均假设消息需要已读未读状态。

客户端与服务端之间,关于阅读状态的命令只需3个,每个命令含请求和应答。

通知消息已读(私聊、群聊通用)

当小宝阅读了一条或若干条消息,需向服务端发送消息已读通知:“众爱卿发的x+y+z消息,朕已阅”。

服务端收到小宝的已读通知时,需完成以下事项:

1)存储消息的已读状态;

2)返回应答给小宝;

3)向已读列表的消息的原始发送者通知消息已读。

对于第“3)”步:

1)私聊的场合,比较好理解,就是发送给私聊的对方;

2)群聊的场合,可很不一样:因为小宝发送的已读消息列表,可能是由众爱卿发送的。考虑这种假设:张三、李四、王五发出的群聊消息,被小宝一下都阅读了,那么小宝发出的已读通知包含的消息列表,需要被IMS分解成3个已读通知(3个不同的消息列表),分别通知给张三、李四、王五,通知内容是“爱卿(不含'"众")发的这些消息,朕已阅”。

查询消息的未读人数(私聊、群聊通用)

消息的发送者,加载消息列表到聊天窗口时,可能需要展示消息是否被已读。

对群聊而言,显示的信息可能是n人未读的提示,那么需要向服务端查询消息的未读人数,由于客户端可能在UI显示自己发出的多条消息,需支持一次请求查询多条消息。

以未读人数的方式来表示消息的阅读状态,统一了私聊、群聊的查询,使得客户端-服务端间的接口更简单,同时使客户端的实现逻辑更统一。

就像下面这样:

1)对于私聊:如果未读人数n>0,表示消息未读;

2)对于群聊:直接显示n人未读即可,当然,当n等于0时表示全部已读。

查询群消息的已读、未读人员清单(群聊)

当客户端希望显示某一条群聊消息的已读、未读人员列表,需向服务端发起查询。

几种具体的已读未读状态存储思路探讨

基本约定

群聊的阅读状态比私聊复杂,因此这里着重讨论群聊的阅读状态。

假设群成员数是n,各个客户端立即IM服务端发送已读通知。服务端需存储每个人的阅读状态,包括那些未读的成员。由于群的成员清单可能变化,比如今天增加了一个成员,则昨天发的消息、与今天发的消息,其接收者列表不一样。

即:

1)同一个群的不同消息,对应的接收者列表可能不一样。

2)换言之,每一条消息都需要记录完整的接收者列表和已读人员列表。

为了方便讨论,本章假设群成员有640人为前提。

存储思路1

每一条消息都维护:

1)接收人员列表receiver_list;

2)已读人员列表read_list。

具体是:

1)IM Server收到一条消息时,用全体群成员构建receiver_list;

2)IM Server收到群成员对这条消息的已读通知时,将此成员加入到read_list。

客户端获取此消息的数据:

1)当需要获取未读人数时,用receiver_list的个数减去read_list的个数;

2)当需要获取已读、未读人员列表时,需用receiver_list减去read_list得到未读人员列表。

那么,思路1每条消息的存储空间是:

640个ID + 不定数量的已读人员ID

存储思路2

每一条消息维护:

1)未读人员列表unread_list;

2)已读人员列表read_list。

具体是:

1)IM Server收到一条消息时,用全体群成员构建unread_list;

2)IM Server收到群成员对这条消息的已读通知时,将此成员从unread_list移出,同时加入到read_list。即时通讯开发

客户端获取此消息的数据:

1)当需要获取未读人数时,直接计算unread_list的个数;

2)当需要获取已读、未读人员列表时,直接返回unread_list和read_list。

那么,思路2每条消息的存储空间是:

未读人员ID + 已读人员ID,合计640个ID

思路2的实现,占用的空间是案1的0.5倍~1.0倍。即案2占用的空间少,但在每次收到客户端的已读通知时,比案1多了一个操作:从unread_list进行减员。

猜你喜欢

转载自blog.csdn.net/wecloud1314/article/details/124660334