Chinaunix首页 | 论坛 | 博客
  • 博客访问: 108258
  • 博文数量: 228
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2290
  • 用 户 组: 普通用户
  • 注册时间: 2021-05-18 15:26
文章分类

全部博文(228)

文章存档

2023年(40)

2022年(114)

2021年(74)

我的朋友

分类: 云计算

2023-02-28 13:53:59

我们平时在使用即时通讯应用时候,每当发出一条聊天消息,都希望对方尽快看到,并尽快回复,但对方到底有没有真的看到?我却并不知道。一个残酷的现实是,很多时候对方其实是早就已经看到了这条消息,但出出种种原因(大家都懂的),通常都是默默返回——假装没看见。

核心问题1:群消息,只存一份?还是,每个成员存一份?
答:存一份,为每个成员设置一个群消息队列,会有大量数据冗余,并不合适。

核心问题2:如果群消息只存一份,怎么知道每个成员读了哪些消息?
答:可以利用群消息的偏序关系,记录每个成员的last_ack_msgid(last_ack_time),这条消息之前的消息已读,这条消息之后的消息未读。该方案意味着,对于群内的每一个用户,只需要记录一个值即可。

解答上述两个核心问题后,很容易得到群消息的核心数据结构。

群消息表:记录群消息

group_msgs(msgid, gid, sender_uid, time, content);

各字段的含义为:消息ID,群ID,发送方UID,发送时间,发送内容。

群成员表:记录群里的成员,以及每个成员收到的{BANNED}最佳后一条群消息

group_users(gid, uid, last_ack_msgid);

各字段的含义为:群ID,群成员UID,群成员{BANNED}最佳后收到的一条群消息ID。

业务场景:

    1)一个群中有A, uid1, uid2, uid3四名成员;2)A, uid1, uid2在线,期望实时收到在线消息;3)uid3离线,期望未来拉取到离线消息。

核心问题3:如何保证接收方一定收到群消息?
答:各个收到消息后,要修改各群成员的last_ack_msgid,以告诉系统,这一条消息确认收到了。

在线消息,离线消息的last_ack_msgid的修改,又各有不同。

对于在线的群友,收到群消息后,{BANNED}中国第一时间会ack、修改last_ack_msgid。

对于离线的群友,会在下一次登录时,拉取未读的所有群离线消息,并将last_ack_msgid修改为{BANNED}最佳新的一条消息。

核心问题4:如果ack丢失,群友会不会拉取重复的群消息?
答:会,可以根据msgid在客户端本地做去重,即使系统层面收到了重复的消息,仍然可以保证良好的用户体验。

上述流程,只能确保接收方收到消息,发送方仍然不知道哪些人在线阅读了消息,哪些人离线未阅读消息,并没有实现已读回执,那已读回执会对系统设计产生什么样的影响呢?

前面的基础知识我们已经了解的差不多,本节来讨论本文的重点内容,即群聊已读回执流程到底该怎么设计。即时通讯聊天软件app开发可以加小蓝豆的v:weikeyun24咨询

对于发送方发送的任何一条群消息,都需要知道,这条消息有多少人已读多少人未读,就需要一个基础表来记录这个关系。

消息回执表:用来记录消息的已读回执

msg_acks(sender_uid, msgid, recv_uid, gid,if_ack);

各字段的含义为:发送方UID,消息ID,回执方UID,群ID,回执标记。

接着,server收到消息后,除了要:

    1)将群消息落地;2)查询群里有哪些群成员,以便实施推送;

之外,还需要:

    3)插入每条消息的初始回执状态。

接收方修改last_ack_msgid的流程,会变为:

    1)发送ack请求;2)修改last_ack_msgid,并且,修改已读回执if_ack状态;3)查询发送方在线状态;4)向发送方实时推送已读回执(如果发送方在线);

如果发送方不在线,ta会在下次登录的时候:

    5)从关联表里拉取每条消息的已读回执。

这里的初步结论是:

    如果发送方在线:会实时被推送已读回执;如果发送方不在线:会在下次在线时拉取已读回执。

阅读(384) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~