IM即时通讯-N-如何保证消息的可靠性展示

这篇具有很好参考价值的文章主要介绍了IM即时通讯-N-如何保证消息的可靠性展示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

结论先行

客户端如何在推拉结合的模式下保证消息的可靠性展示?

  1. 原则: server拉取的消息一定是连续的
  2. 原则: 端侧记录的消息的连续段有两个作用: 1. 记录消息的连续性, 即起始中间没有断层, 2. 消息连续, 同时意味着消息是最新的,消息不是过期的。
  3. 同步协议过载(SyncGapOverflow)时,通过清空会话消息连续段的机制,可以简单粗暴有效的处理同步过载,保证了端侧的连续段一定是连续,并且是最新的
  4. 同步协议过载(SyncGapOverflow)时, 也可以通过端侧不清空连续段的方式, (多个连续段, 中间有间隔)。 会话消息做展示时, 缓存+远端的方式, 保证消息的连续性。 但是这种方式对于历史的消息,可能会存在更新丢失的case, 即消息不是最新的, 因而不推荐使用。如果要使用, 需要配套其他的解决方案。 本文不做展开。
  5. 同步协议中, 需要区分会话消息是新增消息,还是更新消息。两者处理机制不同 新增消息除了入库, 还需要处理消息的连续段; 而更新消息,如果端侧有此消息的缓存, 消息更新,不处理连续段; 没有缓存此消息时, 不需要做消息的更新。
  6. 对于App内发送消息需要特殊处理 App内发送的消息, 仅仅做上屏, 不做连续段, 连续段的更新操作是同步协议下发的此条消息,才会做处理。

引言

同步过载(GAP)指的是,同步协议同步过载,具体是指server向端侧同步时发现端侧是 “首次登录此设备” 或者“ 之前登录过这次再登录”。同步过载的处理细节对于端到端的可靠性展示的重要部分。为了能够更好的解释消息过载, 我们从消息的可靠性入手。
端到端的消息的可靠性, 指的是消息的***可靠性生产***和***可靠性消费***。
此处的消息可以理解为事件。 可靠性生产, 包含了消息不重复生产。
而可靠性消费, 指的是***消息传递时, 不丢失, 不重复, 有序,及时***。

在做及时通讯时, 除了要保证端到端的可靠性传递, 还需要保证展示给用户时, 会话的消息层面的可靠性展示。

什么是可靠性展示

可靠性展示,指的是在用户查看消息时, 展示给用户的消息是***不丢失***的,不重复***的, 并且是***有序,***最新的***的。即有序+不丢+不重+最新

以下我们从简单到复杂, 逐步设计出推拉结合的模式下会话消息的可靠性展示。

通知消息的可靠性展示(普通消费-离店概不负责)

以我们普通的非及时通讯的App为例, 都会有一个消息通知的盒子。 用于接收软件发送给我们的消息。 那么这样的通知消息, 在推拉模式下如何实现呢?

在实现前,先看下这个功能有那些细分的功能。

案例: 西游记开公司了

西游师徒四人开了家西游记的公司, 运营了西游记的App, 主要记录西游记的八十一难以及各路妖怪为什么要这么处理的幕后故事。老板是唐僧, 悟空是CTO, 八戒是运营,沙僧是一线研发。
八戒看到其他的App有通知消息, 于是告知悟空西游记的App也要增加通知消息。悟空指给了沙僧做此项目的负责人。
沙僧先后做了如下的工作,

  1. 功能细分
  2. 技术方案设计
  3. 研发上线等其他工作

细分功能

  1. 展示通知消息的未读数
  2. 展示历史消息
  3. 支持向上翻
  4. 支持实时推送新消息

技术方案

在仅有通知消息的一个单一会话时, 通过***推拉结合***的方式能够很方便的实现此功能。 为了与下文的即时通讯的会话消息的feature匹配,我们将会话单独作为一个功能。与其他篇一致,根据四个场景 用户的新设备登录暂短离线后再次在线用户长期离线后再次在线 以及***用户在线收到消息***做问题解决。

结论先行

  1. 消息的不重复, 不丢失, 有序, 通过推拉结合机制+端内缓存实现的
    不重复和不丢失, 在推送场景下通过ack实现; 在拉取场景下, 通过标记会话的gap, 以及server拉取到的消息是连续的保证的。
    有序, 在推送时保证有序, 在拉取时,保证连续和有序实现的。
  2. 消息与会话完全独立。 消息的未读数由server完全控制。client仅做同步。 如新收到一条未读消息, 那么同步协议需要产生两个事件, 一个是新消息的事件, 另外一个是会话的变更。
  3. 消息过载时,通过清空连续段的方式,可以简单的处理消息过载。即端侧缓存的消息一定是位于连续段中的, 远端仅补充缓存消息两侧消息的方式, 用于保证整体连续。
  4. 消息过载时, 也可以通过增加标记lastMsg与历史消息的连续段的方式。 会话消息做展示时, 缓存+远端的方式, 保证消息的连续性。 这种方式更加标准, 但是却更加复杂。
  5. 消息的同步事件, 仅需要包含新增消息 新增消息是可以追加到队尾的, 消息段自动是连续的。

新设备用户登录

状态图

IM即时通讯-N-如何保证消息的可靠性展示

具体case处理图示
单一连续段的示意图(同步过载即清空)

IM即时通讯-N-如何保证消息的可靠性展示

多连续段的示意图(过载不清空)

IM即时通讯-N-如何保证消息的可靠性展示

逻辑示意图

IM即时通讯-N-如何保证消息的可靠性展示

Case 用户新设备登录同步与拉取会话

端侧标记SyncGapOverflow的处理 直接在会话层面清空连续段。

Case 点击进入会话

检查是否有连续段: 对于端内没有连续段的或者连续段内的消息列表不满足一屏的, 拉取最新消息; 否则, 直接展示端内缓存的消息即可

Case 翻上一页

携带最上方一条消息的时间戳或者消息id, 做上一页的数据拉取: 直接根据时间戳, 或者最上方一条消息的msgId做分割拉取即可。

Case 实时推送

***处理时, 需要根据lastMsg以及连续段做处理***对于有连续段,并且连续段的截止的消息是lastMsg, 消息追加到前一个连续段;对于端侧没有连续段,新增连续段; 如果消息已经位于某个连续段, 不需要处理连续段; 如果消息未位于某个连续段, 新增连续段。

其他场景

  1. 暂短离线后再次在线与在线同步的逻辑一致, 不再赘述。
  2. 用户长期离线后再次在线, 处理逻辑基本一致, 除了上传的同步位点不同, 以及存储的同步位点不同。
  3. 用户在线收到消息: 同在线同步, 不再赘述。

结论

  1. 消息的不重复, 不丢失, 有序, 通过推拉结合机制+端内缓存实现的
    不重复和不丢失, 在推送场景下通过ack实现; 在拉取场景下, 通过标记会话的gap, 以及server拉取到的消息是连续的保证的。
    有序, 在推送时保证有序, 在拉取时,保证连续和有序实现的。
  2. 消息与会话完全独立。 消息的未读数由server完全控制。client仅做同步。 如新收到一条未读消息, 那么同步协议需要产生两个事件, 一个是新消息的事件, 另外一个是会话的变更。
  3. 消息过载时,通过清空连续段的方式,可以简单的处理消息过载。即端侧缓存的消息一定是位于连续段中的, 远端仅补充缓存消息两侧消息的方式, 用于保证整体连续。
  4. 消息过载时, 也可以通过增加标记lastMsg与历史消息的连续段的方式。 会话消息做展示时, 缓存+远端的方式, 保证消息的连续性。 这种方式更加标准, 但是却更加复杂。
  5. 消息的同步事件, 仅需要包含新增消息 新增消息是可以追加到队尾的, 消息段自动是连续的。

支持撤回或者更新的通知消息的可靠性展示(消费升级-退款)

案例: 西游记App出事了, “端午节快乐”的消息要更新或者撤回

八戒在端午节给大家推送了一条端午节快乐, 被老板唐僧看到后, 说端午节的祝福是端午节安康, 而不是端午节快乐。八戒这时候, 找到沙僧, 能不能将已有的推送信息更改掉? 按照一般的推送消息, 推送只能增加, 却不能删除, 或者更新, 这时候就尴尬了。 八戒找唐僧投诉, 唐僧找悟空投诉, 悟空骂你, 为何当时不支持消息更新或者消息撤回。你说当时没说要支持这个呀。。。 挨了骂, 再次重新设计下吧。

相比较普通的通知消息, 支持撤回以及已有消息的更新, 此新增 feature, 更加符合通知消息的特征。 尤其是对于出现上面的紧急情况, 有此利器, 应对自如。

技术方案

结论先行

  1. 将消息撤回 以及 消息更新的操作统一认作是更新消息,并且仅是逻辑删除, 非物理删除。更新消息,如果端侧有此消息的缓存, 做更新, 没有缓存到, 不需要做更新。
  2. 更新消息, 采用出现同步GAP时, 清空连续段的方式是简单而且有效的, 不建议采用标记多个连续段, 否则逻辑会变得特别复杂。
  3. 对于收取到的实时推送消息, 在会话没有过期时, 需要区分是新增消息还是更新消息,对于更新消息的case下, 检查本地是否存在已有的消息, 如果不存在, 忽略即可, 如果存在,更新消息, 不需要处理连续段。
  4. 其他结论: 同普通的消息通知的处理。

新设备用户登录

状态图

同上, 不变

具体case处理图示
同步过载时不清空连续段示意图

IM即时通讯-N-如何保证消息的可靠性展示

在上图的场景下,消息更新可以认为有两个场景:

  1. 同步协议未过载时
  2. 同步协议过载时,需要漫游处理时。

同步协议未过载时(对应的场景: 消息更新-同步协议不过载时),通过同步协议可以直接同步到端侧, 消息入库+更新UI即可。
而同步协议过载时(对应的场景是: 消息更新-端内漫游拉取历史), 用户在进入到会话中, 通过漫游拉取的形式时,由于多连续段并未清空, 因而导致以为消息均是有效的, 最终在将连续段合并起来时, m3的消息,依然是老的消息, 不是server的m3_v2的版本的消息。

同步过载时清空连续段的示意图

IM即时通讯-N-如何保证消息的可靠性展示

同上, 根据两个场景分析,

  1. 同步协议未过载时(对应的场景: 消息更新-同步协议不过载时),通过同步协议可以直接同步到端侧, 消息入库+更新UI即可。
  2. 同步协议过载时(对应的场景是: 消息更新-端内漫游拉取历史), 用户在进入到会话中, 通过漫游拉取的形式时,由于多连续段在发生过载时已经清空, 因而导致以为消息均是无效的, 因而历史消息均是通过漫游拉取下来的。所以消息翻到m3的page时,m3的消息是被server覆盖的, 因而展示的数据便是m3_v2。 保证了消息的准确性。
逻辑示意图

IM即时通讯-N-如何保证消息的可靠性展示

Case 用户新设备登录同步与拉取会话

同上, 不变

点击进入会话

同上, 不变

翻上一页

同上, 不变

实时推送
  1. 将消息撤回 以及 消息更新的操作统一认作是更新消息,并且仅是逻辑删除, 非物理删除。
  2. 对于收取到的实时推送消息, 需要区分是新增消息还是更新消息,对于更新消息的case下, 不需要处理连续段。

其他场景

  1. 暂短离线后再次在线与在线同步的逻辑一致, 不再赘述。
  2. 用户长期离线后再次在线, 如果采用不清空连续段的方式, 即在后方追加GAP的形式, 更新消息会存在问题, 因为没有办法感知到历史消息的变化。 因而采用单一连续段的形式是比较合适的。
  3. 用户在线收到消息: 同在线同步, 不再赘述。

结论

  1. 将消息撤回 以及 消息更新的操作统一认作是更新消息,并且仅是逻辑删除, 非物理删除。更新消息,如果端侧有此消息的缓存, 做更新, 没有缓存到, 不需要做更新。
  2. 更新消息, 采用出现同步GAP时, 采用清空连续段的方式
  3. 对于收取到的实时推送消息, 在会话没有过期时, 需要区分是新增消息还是更新消息,对于更新消息的case下, 检查本地是否存在已有的消息, 如果不存在, 忽略即可, 如果存在,更新消息, 不需要处理连续段。
  4. 其他结论: 同普通的消息通知的处理。

正常IM单个会话的可靠性展示(生产消息+消费消息)

案例: 唐僧要把通知消息变为公众号对话

西游记App的用户越来越多, 用户对于通知类的消息, 每次都需要点击到具体的消息,而为了促进用户的活跃以及问题能够及时反馈, 唐僧说, 这个通知消息里面,要支持用户跟我们互动: 如我们发起了一个活动, 直接推送一个文案到这个消息里面, 用户可以直接回复消息。 以及用户常见的疑问, 在我们这个里面,我们可以直接解决。悟空说, 这个活本来也是你干的, 现在需要继续想解决方案和实施方案。

思考

核心问题: 生产消息与消费消息两者并存, 如何解决连续性的问题。
上面提到的通知消息以及通知消息支持撤回或者更新的case,解决了生产消息连续段的标记。

而支持发送消息与前面的仅仅展示型的消息是不同的。 发送消息是生产消息,同步与拉取消息是消费消息。出现了生产, 那么端上的处理机制会产生比较大的变化。如:

  1. 发送消息时, 消息未发送成功, 如何跟已经发送成功的消息混排?
  2. 消息发送成功后, 连续段应该如何处理?
  3. 弱网情况下, 如果消息没有同步下来, 但是用户先去发送消息了,这时候连续段又应该如何处理?
  4. 弱网情况下, 用户先发送消息, 并且成功了, 稍后同步过载的事件通知到端上了, 此时的连续段有应该如何处理?
    此时我们会发现, 增加了发送消息后, 技术方案会变得复杂了许多。

技术方案

思路:

  1. 连续段的处理逻辑: 消息漫游触发变更连续段, server的同步事件触发变更连续段, 本地发送的消息, 不触发连续段的计算。
  2. 本地发送的消息虽然不参与连续段的计算, 但是却需要参与数据的展示, 否则, 会导致消息丢失。

根据这个思路, 那么弱网的两种case也是迎刃而解的。

  1. 弱网,消息同步失败,用户先发送消息,发送成功, 稍后,在网络恢复后, 同步消息会同步到端上,只不过此次弱网情况下, 对于用户而言, 有些消息看不到
  2. 弱网, 同步过载事件同步失败, 用户先发送消息, 发送成功, 稍后, 在网络恢复后, 同步过载的事件同步到端上。端上清空连续段, 再次进入到会话时,通过漫游更新的消息内容。

结论先行

  1. 连续段的处理逻辑: 消息漫游触发变更连续段, server的同步事件触发变更连续段, 本地发送的消息, 不触发连续段的计算。
  2. 本地发送的消息虽然不参与连续段的计算, 但是却需要参与数据的展示, 否则, 会导致消息丢失。
  3. 其他结论, 同支持撤回或者更新的通知消息。

具体case处理图示

由于过载不清空连续段存在消息不是最新的case, 因而以下我们只展示过载时清空连续段的方案。
IM即时通讯-N-如何保证消息的可靠性展示

结论

  1. 连续段的处理逻辑: 消息漫游触发变更连续段, server的同步事件触发变更连续段, 本地发送的消息, 不触发连续段的计算。
  2. 本地发送的消息虽然不参与连续段的计算, 但是却需要参与数据的展示, 否则, 会导致消息丢失。
  3. 其他结论, 同支持撤回或者更新的通知消息。

总结

上文通过三种场景,普通通知消息(不支持撤回/更新历史消息), 支持更新历史消息的通知消息,到最终的正常IM单个会话,通过三种场景, 最终得出客户端如何在推拉结合的模式下保证消息的可靠性展示的关键思路:文章来源地址https://www.toymoban.com/news/detail-408399.html

  1. 原则: server拉取的消息一定是连续的
  2. 原则: 端侧记录的消息的连续段有两个作用: 1. 记录消息的连续性, 即起始中间没有断层, 2. 消息连续, 同时意味着消息是最新的,消息不是过期的。
  3. 同步协议过载(SyncGapOverflow)时,通过清空会话消息连续段的机制,可以简单粗暴有效的处理同步过载,保证了端侧的连续段一定是连续,并且是最新的
  4. 同步协议过载(SyncGapOverflow)时, 也可以通过端侧不清空连续段的方式, (多个连续段, 中间有间隔)。 会话消息做展示时, 缓存+远端的方式, 保证消息的连续性。 但是这种方式对于历史的消息,可能会存在更新丢失的case, 即消息不是最新的, 因而不推荐使用。如果要使用, 需要配套其他的解决方案。 本文不做展开。
  5. 同步协议中, 需要区分会话消息是新增消息,还是更新消息。两者处理机制不同 新增消息除了入库, 还需要处理消息的连续段; 而更新消息,如果端侧有此消息的缓存, 消息更新,不处理连续段; 没有缓存此消息时, 不需要做消息的更新。
  6. 对于App内发送消息需要特殊处理 App内发送的消息, 仅仅做上屏, 不做连续段, 连续段的更新操作是同步协议下发的此条消息,才会做处理。

到了这里,关于IM即时通讯-N-如何保证消息的可靠性展示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何保证 RabbitMQ 的消息可靠性?

    项目开发中经常会使用消息队列来 完成异步处理、应用解耦、流量控制等功能 。虽然消息队列的出现解决了一些场景下的问题,但是同时也引出了一些问题,其中使用消息队列时如何保证消息的可靠性就是一个常见的问题。 如果在项目中遇到需要保证消息一定被消费的场景

    2024年02月07日
    浏览(49)
  • rabbitmq如何保证消息的可靠性

    RabbitMQ可以通过以下方式来保证消息的可靠性: 在发布消息时,可以设置消息的delivery mode为2,这样消息会被持久化存储在磁盘上,即使RabbitMQ服务器重启,消息也不会丢失。 可以创建持久化的队列,这样即使RabbitMQ服务器重启,队列也不会丢失。 在消费者端,可以 设置手动

    2024年01月23日
    浏览(54)
  • Kafka—工作流程、如何保证消息可靠性

    分布式事件流平台 。希望不仅仅是存储数据,还能够数据存储、数据分析、数据集成等功能。消息队列(把数据从一方发给另一方),消息生产好了但是消费方不一定准备好了(读写不一致),就需要一个中间商来存储信息,kafka就是中间商 架构图如下: 名称 解释 Broker 消

    2024年02月11日
    浏览(52)
  • rabbitmq如何保证消息的可靠性传输(简述版本)?

    我需要从三点去考虑, 生产者弄丢了数据,生产者将消息发送的Exchange并且路由到队列 队列需要将消息给它持久化 消费者要成功消费队列中的消息 RabbitMQ提供了confirm机制,保证了消息消息发送的Exchange交换机,那么还提供了return机制,可以保证消息从exchange路由到队列中,如

    2024年02月13日
    浏览(37)
  • RabbitMQ如何保证消息的可靠性6000字详解

    RabbitMQ通过生产者、消费者以及MQ Broker达到了解耦的特点,实现了异步通讯等一些优点,但是在消息的传递中引入了MQ Broker必然会带来一些其他问题,比如如何保证消息在传输过程中可靠性(即不让数据丢失,发送一次消息就会被消费一次)?这篇博客将详细从生产者,MQ B

    2024年02月16日
    浏览(37)
  • 如何保证消息的可靠性+延迟队列(TTL+死信队列+延迟队列)

    目录 1.如何保证消息的可靠性 1.1.消息的可靠投递 confirm机制 return机制 1.2.如何保证消息在队列中不丢失 1.3.确保消息能可靠的被消费掉 2.延迟队列 2.1.TTL 2.2.死信队列 2.3.延迟队列 3.如何防止消费者重复消费消息 在生产环境中由于一些不明原因,导致 rabbitmq 重启,在 RabbitMQ 重

    2024年02月15日
    浏览(60)
  • RabbitMQ如何保证消息可靠性,看完这篇文章佬会有新的理解

    前言:大家好,我是小威,24届毕业生,在一家满意的公司实习。本篇文章将详细介绍RabbitMQ的消息可靠性机制,如消息丢失,消息重复性消费,消息积压等问题。 如果文章有什么需要改进的地方还请大佬不吝赐教 👏👏。 小威在此先感谢各位大佬啦~~🤞🤞 🏠个人主页:小

    2024年02月03日
    浏览(53)
  • RabbitMQ-保证消息可靠性

    消息从发送,到消费者接收,会经理多个过程: 其中的每一步都可能导致消息丢失,常见的丢失原因包括: 发送时丢失: 生产者发送的消息未送达exchange 消息到达exchange后未到达queue MQ宕机,queue将消息丢失 consumer接收到消息后未消费就宕机 针对这些问题,RabbitMQ分别给出了

    2024年02月07日
    浏览(52)
  • RabbitMQ保证消息的可靠性

    消息从发送,到消费者接收,会经理多个过程: 其中的每一步都可能导致消息丢失,常见的丢失原因包括: 发送时丢失: 生产者发送的消息未送达exchange 消息到达exchange后未到达queue MQ宕机,queue将消息丢失 consumer接收到消息后未消费就宕机 针对这些问题,RabbitMQ分别给出了

    2024年02月19日
    浏览(49)
  • TCP消息传输可靠性保证

    三次握手 TCP 提供面向有连接的通信传输。面向有连接是指在数据通信开始之前先做好两端之间的准备工作。 所谓三次握手是指建立一个 TCP 连接时需要客户端和服务器端总共发送三个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发。 第一次握手:客

    2024年02月12日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包