1.介绍

 

 在即时消息系统中,尤其是在企业应用场景中,消息的已读和未读状态是一个很强的需求。

 

 以阿里美甲为例,美甲的产品定位是用于商业交流,其“强制阅读回执”功能使职场人士无法“假装不在线”或“假装不接收”。更重要的是,群聊功能的“阅读后强行收条”甚至可以知道谁读了和谁没读(老板的福音)。

 

 从存储空间谈即时通讯群聊信息的读和未读功能的实现

 ▲指甲中的群聊信息已阅读且未阅读。

 

 这个函数看起来很酷,但是使用起来很长。事实上,技术实现并不容易。

 

 然后,对于已读和未读状态:

 

 1)如果是私人聊天:消息的阅读状态容易实现,性能和存储没有问题;

 2)在群聊的情况下,考虑到存储和处理性能,尤其是在云环境下,如何有效处理群聊的已读和未读状态是一个值得讨论的话题。

 

 这里提到的“高效率”包括三个方面:

 

 1)存储空间;

 2)处理速度;

 3)传输的字节数。

 

 本文将从服务器的角度讨论读取和未读取状态,以及在具体技术实现中对存储空间占用的不同思考。能力有限,权作个人笔记,欢迎交流。

 

 本文已在“即时通讯技术圈”公开发表。请注意:

 从存储空间_ 52im_ QR _即时通讯technical circle _ 400 px . png谈即时消息群聊消息的读和未读功能的实现

 ▲本文关于公开号码的链接是:https://mp.weixin.qq.com/s/yUkKPOBsdqLlxiFrGmwFRQ

 2.内容审查

 

 在收录本文之前,杰克·江建议原作者分享一些具体的技术要点,但由于作者忙于工作,本文中的一些关键技术要点将在以后进一步发展。

 

 因此,本文可以作为即时聊天(主要是群聊)中阅读和未阅读功能基本实现的参考,但不建议盲目相信本文的结论或方案,以免被一些不够具体的技术指标所误导。

 3.相关文章

 

 如果您想了解更多关于即时消息群聊中已读和未读功能的实现逻辑,可以进一步阅读干货文章“如何实现即时消息群聊消息的已读回执功能?”(强烈推荐)。

 

 如果您对即时消息中的已读和未读功能感到困惑,可以参考微信中已读和未读功能的设计方向。详情请参考“关于即时通讯流行功能的思考:为什么微信没有信息“阅读”功能?”.

 

 关于即时消息群聊技术的更多文章,请参考本文的附录。

 4.已读和未读状态的交互流程

 

 在接收者读取由发送者发送的即时消息聊天消息之后,是否要求读取器通知它已经被读取可以由系统配置、组织配置、组配置等来确定。,或由发送方根据业务要求。在下面的讨论中,假设邮件需要已读和未读状态。

 

 在客户机和服务器之间,只有三个读取状态的命令,每个命令包含一个请求和一个响应。

 

 4.1已阅读通知消息(私人聊天和群聊很常见)

 

 当读到一条或几条消息时,他应该向服务器发送一条消息阅读通知:“我已经阅读了钟发来的x+y+z消息”。

 

 当服务器收到鲍晓的读取通知时,它需要完成以下项目:

 

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

 2)回复鲍晓;

 3)通知阅读列表中消息的原始发送者消息已经被阅读。

 

 对于步骤“3”:

 

 1)更好地理解私人聊天的场合,即发送给私人聊天的另一方;

 2)群聊的场合非常不同:鲍晓发送的阅读信息列表可能是艾青发送的。假设:张三、李四、王五发送的群聊信息都被鲍晓阅读过,那么鲍晓发送的阅读通知中包含的信息列表需要被IMS分解成三个阅读通知(三个不同的信息列表),分别通知张三、李四、王五。通知的内容是“我已经阅读了艾青发来的这些信息(不包括“公开”)

 

 以下是一般逻辑流程图:

 存储空间中即时消息群聊消息读与未读功能实现的探讨

 

 4.2未读查询消息数(私人聊天和群聊很常见)

 

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

 

 对于群聊,显示的信息可能是提示n个人没有阅读它,因此有必要查询来自服务器的未读消息数。由于客户端可能会在用户界面中显示自己发送的多条消息,因此有必要支持一次查询多条消息的请求。

 

 未读数用于表示消息的阅读状态,统一了私人聊天和群聊的查询,使客户端和服务器的接口更加简单,客户端的实现逻辑更加统一。

 

 就像这样:

 

 1)对于私人聊天:如果未读数字n>0,则消息是未读的;

 2)对于群聊:直接显示n个人没有读过,当然,当n等于0时,表示所有人都读过。

 

 4.3查询已阅读和未阅读群发信息的人员列表(群聊)

 

 当客户端想要显示群聊消息的已读和未读人员列表时,它需要向服务器发起查询。

 

 总体逻辑流程图如下:

 从存储空间角度谈即时通讯群聊信息的读和未读功能的实现

 5.关于已读和未读状态的几种具体存储思想的讨论

 

 5.1基本协议

 

 群聊的阅读状态比私人聊天更复杂,因此本文重点研究群聊的阅读状态。

 

 假设组成员的数量为n,每个客户端立即向即时消息服务器发送一个读取通知。服务器需要存储每个人的阅读状态,包括那些未读的成员。因为组成员的列表可能会改变,例如,如果今天添加了一个成员,则昨天发送的邮件的收件人列表与今天发送的邮件的收件人列表不同。

 

 那就是:

 

 1)同一组中的不同邮件可能有不同的收件人列表。

 2)换句话说,每封邮件都需要记录一份完整的收件人和读者名单。

 

 为了便于讨论,本章假设有640个小组成员。

 

 5.2存储理念1

 

 每条消息都得到维护:

 

 1)接收者列表接收者列表;;

 2)阅读阅读人员列表。

 

 具体来说:

 

 1)当1)即时消息服务器收到消息时,它使用所有组成员来建立接收者列表;;

 2)当2)即时消息服务器收到组成员已阅读此消息的通知时,它会将此成员添加到read_list。

 

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

 

 1)当需要获取未读人数时,从接收人列表数中减去已读列表数;

 2)当您需要获得已读和未读人员的列表时,您需要从接收者列表中减去已读列表以获得未读人员列表。

 

 然后,想法1中每个消息的存储空间是:

 640身份证+无限数量的已读身份证

 

 

 

 5.3存储理念2

 

 维护每条消息:

 

 1)未读人员列表未读列表;;

 2)阅读阅读人员列表。

 

 具体来说:

 

 1)当1)即时消息服务器收到消息时,它使用所有组成员来建立未读列表;;

 2)当2)即时消息服务器收到群成员已阅读此消息的通知时,它将从未读列表中删除此成员,并同时将其加入读列表。

 

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

 

 1)当需要获取未读人数时,直接计算未读人数列表;

 2)当您需要获取已读或未读人员的列表时,直接返回未读列表和已读列表。

 

 然后,想法2中每个消息的存储空间是:

 未读人员标识+已读人员标识,总共640个标识

 

 

 实现想法2所占用的空间是案例1的0.5倍到1.0倍。也就是说,案例2占用的空间更少,但是每当它从客户端接收到读取通知时,它比案例1多了一个操作:从未读列表缩小。

 

 5.4存储思维3(我的实现)

 

 5.4.1)讨论第5.2节和第5.3节的缺点:

 

 第5.2节和第5.3节可以满足功能要求,但存在巨大的存储浪费。

 

 这个小组有640人。如果每天群聊中有1024条消息,并且个人标识以4字节存储和计算,则该群的每日消息阅读状态所消耗的空间为:

 

 第5.2节想法1:1024 *(640 * 4+阅读人数* 4),范围从2.5兆到5兆;

 第5.3节想法2: 1024 * 640 * 4,等于2.5MB

 

 这只是一个组在一天内生成的阅读状态数据。如果它运行在云平台上,这个功能单独消耗的空间,呵呵~ ~

 

 离题:如果成员不是存储在4字节整数中,他们应该使用字符串,比如“1123356777”,这更令人印象深刻。

 

 5.4.2)如何减少存储空间:

 

 考虑到群组成员不会一直变化,在大多数情况下,群组成员的列表相对稳定,今天的列表和上周的列表甚至可能是相同的,因此数百条消息,甚至数万条消息,可能对应于相同的群组成员列表。

 

 因此,它引出了本文的主要观点:

 考虑将组成员列表与不同的消息共享,也就是说,将消息的阅读状态与组成员列表分开存储,并记录它们之间的关联。

 

 

 

 假设平均每1024条消息共享一个组成员列表。在发送1024条消息后,组成员发生变化,然后需要一个新的组成员列表。

 

 那么这1000条消息的阅读状态所占用的空间是:

 群组成员列表空间+1024条消息的阅读状态:640 * 4+1024 *每条消息的阅读状态占用的空间

 

 

 

 在拥有群组成员列表的前提下,如何减少每条消息的阅读状态所占用的空间?

 人们自然会想到用位来代表已经阅读过的人,因为一个32位的整数可以代表32个人的阅读状态。位的顺序只需要与组成员列表的顺序一致。

 

 

 

 当没有人读取消息时,读取状态占用0字节;当组中的每个人都读取时,它占用最大的空间,即640/32 = 20字节。

 

 因此,优化后,千条消息的读取状态所占用的空间从2.5 KB到(2.5 KB+1024 * 20B),即从2.5 KB到22.5 KB,与第5.2节中的思路1和第5.3节中的思路2相比,大大减少了。

 

 如下图所示:

 从存储空间角度探讨即时消息群聊消息的读和未读功能的实现

 

 此表单的先决条件:

 

 1)一组640人;

 2)对应于该组的1024条连续消息的组成员列表是稳定的。

 

 退一步说,即使这1024条消息对应的组成员列表不稳定,中间改变了10次,也只有2.5KB * 10,即多25KB的存储空间,这与情况1和情况2相比仍然具有很大的优势。

 6.如何提高已读和未读状态的处理速度

 

 鲍晓给公司集团发了一条信息。让我给你介绍一下新的女同事。每个人都立即检查了信息,立即,瞬间和闪电。它觉得一秒钟后将失去杀死女神的机会,这意味着超过N个阅读通知将在一瞬间发送到即时消息。

 

 这些消息的处理流程是相同的:

 

 1)这些操作可以结合起来,以批量形式存储和转发;

 2)因为存储消息的读取状态是一个设置位的过程,所以不存在互斥问题,即使在分布式环境中也可以放心操作;

 3)消息对应的成员列表信息可以临时缓存在内存对象中,减少查询输入输出,提高效率。

 

----------------------------------------------------------------------------------

哇谷im_im即时通讯_私有云_公有云-哇谷云科技官网-JM沟通

IM下载体验 - 哇谷IM-企业云办公IM即时聊天社交系统-JM 沟通下载

IM功能与价格 - 哇谷IM-提供即时通讯IM开发-APP搭建私有化-公有云-私有化云-海外云搭建

新闻动态 - 哇谷IM-即时通讯热门动态博客聊天JM沟通APP

哇谷IM-JM沟通热门动态博客短视频娱乐生活

关于哇谷-哇谷IM-提供企业即时通讯IM开发-语音通话-APP搭建私有化-公有云-私有化云-海外云搭建

联系我们 - 哇谷IM-即时通讯IM私有化搭建提供接口与SDK及哇谷云服务

即时通讯IM融云世界

IM即时通讯钉钉技术:企业IM钉钉在后端架构上的优越之处

新的市场叫板环信、融云、腾讯云!开源版IM即使聊天工具

企业IM即时通讯聊天办公APP钉钉技术分析交流

哇谷云-怎么样正确认识海外云服务器

公有云和私有云之间有什么区别?类似融云、环信云、网易云、哇谷云?