单聊未读消息计数
未读消息的计数,分为两个部分:增加和减少
其中,未读消息计数的增加,是由数据库(redis)在写入消息的同时,增加对应接收方的未读消息计数
在线
用户在线时,客户端会实时收到消息,未读消息计数的显示由客户端处理,服务端同时记录在数据库中
1.如果用户未打开对话窗口,则根据接收到的消息数量显示未读消息计数
2.如果用户打开对话窗口,则客户端向服务端发送未读消息计数清零的请求,窗口打开时,每收到一条消息发送一次清零请求(可优化)
离线
用户离线,再次上线后,客户端拉取未读消息计数,并显示给用户。上线以后就是在线状态的逻辑了
未读消息 的 key 设计
群聊未读消息计数
群聊的难点在于,一个人发送一条消息,要确保所有人的未读消息计数增加,这带来写扩散的压力
但是,必须增加每个人的未读消息计数吗
不是的,未读消息计数是客户端上线后拉取的,只要保证客户端能正确获取到未读消息计数就行
优化前
服务端维护每个群聊成员的未读群消息计数,就像单聊一样
每有一条群聊消息,增加所有人的未读消息计数(如果1个人发1条消息,千人群要操作1000次redis,很快会达到redis写能力瓶颈)
客户端直接拉取对应用户的群聊未读消息计数
客户端在线时,用户若已读消息,客户端要向服务端请求清零消息未读计数,逻辑同单聊
优化后
服务端不再维护每个群聊成员的群消息未读计数,而是记录整个群聊的消息总数,和每个群成员的已读消息数量
客户端拉取未读消息计数时,服务端返回 消息总数 - 已读消息数量
优化了哪里呢?
解决了写扩散的问题,一个人发消息,只会进行一次写操作(消息总数+1),而不是1000次(增加每个人的未读计数)
客户端行为的改变:
客户端请求清零消息未读计数 —> 客户端上报用户已读消息数量
具体逻辑:
1.用户打开群聊消息窗口,则已读消息数量 += 读前的未读消息数量
2.用户一直打开消息窗口,客户端每收到一条消息,请求增加一次已读消息数量
群聊消息总数 和 用户已读消息数 的 key 设计
点击获取更多Linux C/C++开发学习资料