IM即时通讯-6-已读回执的方案设计

背景-为什么展示已读未读

部分即时通讯软件会选择展示给用户已读未读, 主要是***快速感知对方的阅读状态, 感觉到自己受重视, 方便做下一步操作***。
如果要带点高度的讲,满足软件所代表的关键用户的诉求

什么场景下要展示已读回执

  1. toB的场景
    如钉钉, 企业微信。已读未读, 是为了满足企业运作核心效率(即老板视角)的诉求, 已读未读, 有一种压迫感,用户A看了用户B的消息, 是需要快速响应的。
  2. 客服的场景。
    电商客服, 售后服务。 已读未读。 是为了满足消费者的快速响应的诉求, 已读未读, 也是有一种压迫感, 客服看了用户的反馈信息, 是需要快速给出响应的。

既然有诉求, 开发便需要设计和实现。在开发之前, 需要定义清楚什么是已读未读?

什么是已读未读?

不同的产品形态, 对于已读未读的定义是不同的。

  1. 用户看到的最新消息以及以前的消息都算作已读: 对于已读未读定义不严格时,用户看到最新的消息,便认作历史消息都当做已读。
  2. 用户点击的消息才算作已读: 像一些通知类的消息,用户真正点击了消息, 才当做是已读。
  3. 用户看到的消息才算作已读,没有看到的不算已读: 像钉钉这样的产品, 消息真正曝光到用户的屏幕上, 才算是已读。

如何设计实现

针对定义的已读未读的三种定义, 实现起来整体可以分为两类。

  1. 会话级别的已读未读:用户看到的最新消息以及以前的消息都算作已读
  2. 消息级别的已读未读: 用户点击的消息才算作已读 + 用户看到的消息才算作已读,没有看到的不算已读

实现会话级别的已读未读

上报时机: 在消息上屏后, 检查接收的最新消息的最新时间戳是否与已经存储的阅读的时间戳的关系即可。如果大于, 更新屏幕上的消息的状态为已读。并且同步到server, 否则,不做调整。
上报存储:由于已读只是一个时间戳, 并且是跟用户+会话, 一一对应, 因而消息的已读未读, 存储在会话中即可。 每个用户的每个会话有自己的已读的时间戳。
IM即时通讯-6-已读回执的方案设计_第1张图片
更新消息已读状态的方案
针对会话级别的已读更新消息的方案, 简单做的话, 可以直接单会话完整信息的更新(即此会话的完整模型信息更新, 如会话的title, lastMsg, 已读的position等完整信息, 推拉均可)的topic, 而复杂做, 可以将会话更新的topic进行二级细分,如仅拉取/推送会话的已读情况。 非高并发,大容量的case下,建议直接采用单会话的完整信息的推送/拉取。

server侧的存储: server侧, 单聊的case由于同一个会话, 两人记录的均是对方的消息的最新时间戳, 因而是不一致的。 需要存储到两人私有信息中。 群聊的case下, 同单聊, 记录最新的接收消息的时间戳也是可以的, 记录到个人的会话的收件箱中。

实现消息级别的已读未读

消息级别根据上文, 存在两种情况, “用户点击的消息才算作已读” + “用户看到的消息才算作已读,没有看到的不算已读”
上报时机: 消息曝光/消息点击时, 检查消息的已读未读状态,针对未读的消息, 上报给server即可。
上报存储: 由于是单条消息级别的, 消息是跟用户+会话+消息, 一一对应的, 因而每条消息的已读未读,存储在用户的单聊消息中即可。
IM即时通讯-6-已读回执的方案设计_第2张图片
更新消息已读状态的方案*
同会话级别的已读未读方案, 有消息完整内容更新, 以及消息局部更新(即仅更新消息的已读未读)。
对于不复杂的业务, 可以采用消息完整内容更新。 但是对于复杂的业务, 建议采用消息局部更新或者消息合并更新的策略。

***server侧的存储***由于消息已读未读,是一个公众的状态, 因而是可以被大家都阅读到的。 对于单聊, 记录到公众的消息中, 对于非单聊, 可以采用的会话中, 仅记录消息的已读任务, 未读人数,而不记录具体的人是那些,采用分表的方式, 单独记录到消息的已读表中以及未读表中。对于企业级的千人群, 万人群的特殊case, 还有特殊的优化逻辑。可以参考下企业微信的IM架构设计揭秘:消息模型、万人群、已读回执、消息撤回等

你可能感兴趣的:(即时通讯,端到端解决方案,思考心得,方案设计,即时通讯,已读回执,企业微信,钉钉)