如何确保单聊消息100%送达?揭秘消息可靠传输的核心机制!

简介: 哈喽,大家好!我是技术好朋友小米,今天聊聊单聊消息的可靠传输。通过TCP的超时、重传、确认机制,结合去重和离线消息优化,我们可以设计出高效、可靠的消息传输系统。希望今天的分享能给大家带来帮助!如果有问题,欢迎留言交流。



哈喽,大家好!我是你们的技术好朋友小米,今天我们聊聊单聊消息的可靠传输。这个话题有点酷哦,尤其对于那些正在开发即时通讯项目的小伙伴们。想想你给好友发消息,却总担心消息会不会送达,离线消息会不会丢失,这种场景是不是很常见?不用担心,咱们可以通过一套可靠传输机制来解决!今天我们就来一起拆解这个“套路”。

TCP保证消息可靠传输的三板斧

首先,聊到消息的可靠传输,不得不提我们熟知的TCP三板斧超时、重传、确认。这些基本概念支撑了现代网络传输的可靠性:

  • 超时:每次发送消息后,等待一段时间,如果没有得到回复,就会触发超时机制。
  • 重传:当超时发生时,TCP会自动重发未确认的消息,直到收到确认消息或重试次数耗尽。
  • 确认:每当收到消息时,接收方必须返回一个确认报文,告诉发送方“你的消息我收到了”。

消息传输通过这三个步骤保障,确保每个数据包都不会丢失或重复发送。

消息的三类报文:R、A、N

在设计单聊的消息可靠传输时,通常使用三种不同类型的报文来进行交互,分别是:

  • 请求报文 (Request,R):由客户端发起,向服务器发送的消息请求。
  • 应答报文 (Acknowledge,A):由服务器返回,确认接收客户端的请求。
  • 通知报文 (Notify,N):由服务器主动发送给客户端,通知该客户端有新消息。

简单理解就是,客户端发出消息请求(R),服务器回应确认(A),然后服务器再通知客户端对方是否收到消息或有新消息(N)。

在线消息流程详解

为了让大家更直观理解消息在网络中如何可靠地传输,我们来详细走一遍在线消息传输的整个流程。咱们以一个简单的单聊示例为基础:

  1. A -> 服务器:A用户给服务器发消息,消息是MSG(Request)。
  2. 服务器 -> A:服务器收到A发来的消息,回复一个MSG(Acknowledge),表示消息收到了。
  3. 服务器 -> B:服务器把A发来的消息转发给B,这里发送的是MSG(Notify)。
  4. B -> 服务器:B收到服务器的消息后,发送ACK,确认收到了这条消息。
  5. 服务器 -> A:服务器收到B的确认后,回复给A一个ACK,表示消息成功传达给了B。

这个流程总共6个报文来回传递,确保消息从A到B的可靠传输,每个节点都有ACK确认机制,保证每个消息都能送达。

超时、重传与确认机制

可靠传输的核心之一就是超时与重传机制。我们来看下A用户发送消息时的场景:

  1. 发送消息:A用户发出MSG,并在本地记录这条消息,等待服务器的确认ACK。
  2. 消息重传:如果A没有在设定的时间内收到服务器的MSG确认,就会触发超时机制,重新发送MSG。A还需要维护一个等待ACK的队列,记录哪些消息还未被确认。
  3. 确认ACK:每次A收到服务器的ACK,表示B用户成功接收到消息了,A会从等待ACK的队列中删除对应的消息。

通过这样的机制,消息必达得以实现,即使在网络不稳定的情况下,重发机制也能确保消息最终送达。

去重机制

同时,为了避免重传导致消息重复的问题,服务器和客户端都需要有一套去重机制。每条消息会带上一个唯一的ID,服务器在收到消息时,会检查这个ID是否已经处理过。如果处理过,则忽略该消息,避免重复推送给接收方。

离线消息处理:原方案 vs 优化方案

在单聊场景中,处理离线消息也是至关重要的一环。如果用户在不在线时收到消息,我们该如何保障消息的传递和回执呢?来看下两种方案:

原方案

用户上线后,客户端会主动向服务器拉取离线消息,流程如下:

  • 检测离线:客户端检查用户是否离线。
  • 拉取消息:客户端向服务器发出拉取指定时间段内的消息请求。
  • 返回消息:服务器响应,发送离线期间的消息给客户端。

这种方案虽然简单,但在面对海量消息时效率不高,尤其当消息量非常大时,拉取消息的时间可能会很长,导致用户体验卡顿。

优化方案

针对原方案的不足,我们可以对离线消息的处理进行优化:

  • 全量拉取计数:用户可以勾选全量拉取选项,服务器首先返回离线消息的总条数,当用户需要时再点击具体查看。
  • 默认拉取最近消息:如果用户未选择全量拉取,则服务器只返回最近的全部离线消息,客户端可以根据用户的id进行计算,筛选消息。
  • 分页拉取:为了避免一次拉取过多消息,导致客户端卡顿,可以将全量离线消息分页拉取。客户端通过异步线程分批获取消息,减少瞬时压力。
  • ACK报文优化:当客户端拉取离线消息时,可以将ACK和第二次分页拉取的请求合并,从而减少来回交互次数,提高效率。

通过这些优化,我们能让离线消息传输更高效,确保即使消息量再大,用户也能流畅地收到所有消息。

END

单聊消息的可靠传输涉及到多方面的技术细节,既要保证在线消息的实时可靠传输,也要妥善处理离线消息。通过TCP的超时、重传、确认机制,结合去重离线消息优化,我们可以设计出一套高效、可靠的消息传输系统。

在实际项目开发中,不同场景下的处理逻辑可能会有所不同,大家可以根据自己的需求进行定制。

希望今天的分享能给你们带来帮助!如果有任何问题,欢迎在评论区留言,我是小米,咱们下次见!

我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号软件求生,获取更多技术干货!

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
机器学习/深度学习 分布式计算 安全
联邦学习的简要概述
联邦学习(Federated Learning, FL)是一种分布式机器学习方法,旨在保护数据隐私的同时,利用多方数据进行模型训练。
1831 5
|
前端开发 Java 程序员
牛皮的程序猿后端返回值怎么定义
在后端接口封装中,通常会统一返回数据格式,确保稳定性和可预测性。常见的模式包括状态码(如`code`或`ret`)、状态信息(`message`或`msg`)、核心数据(`data`)。`success`字段提供了一种直观判断接口是否成功的标志。例如:
646 155
|
Rust Ubuntu Linux
【一起学Rust | 进阶篇 | RMQTT库】RMQTT消息服务器——安装与集群配置
【一起学Rust | 进阶篇 | RMQTT库】RMQTT消息服务器——安装与集群配置
1246 0
|
监控 NoSQL Redis
Redis Sentinel:秒杀系统背后的可靠性保障神器!
本文详细介绍了如何在个人项目中利用 Redis 哨兵模式保障系统的可靠性与高可用性。哨兵模式通过监控主从服务器状态、自动故障转移和通知客户端等功能,确保在主服务器宕机时系统仍能正常运行。适用于读请求多于写请求的场景,如秒杀系统,能有效缓解数据库压力。同时也探讨了哨兵模式在高并发场景下的优化方法及潜在缺陷,帮助开发者更好地应用该模式。
452 8
Redis Sentinel:秒杀系统背后的可靠性保障神器!
|
网络协议 安全 程序员
网络原理-UDP/TCP详解
网络原理-UDP/TCP详解
网络原理-UDP/TCP详解
|
人工智能 运维 安全
阿里云容器服务ACK:高效管理云上应用的容器化解决方案
阿里云容器服务ACK(Alibaba Cloud Container Service for Kubernetes)为开发者提供了一套全面的容器化管理解决方案,旨在简化云上应用的部署、运维和管理。本文将深入探讨ACK的功能、优势及应用场景,为开发者展现容器化技术在云环境下的强大能力。
1297 0
|
JavaScript API
卷死了!再不学vue3就没有人要你了!速来围观vue3新特性
该文章强调了学习Vue3的重要性,并详细介绍了Vue3相较于Vue2的新特性与改进,包括Composition API、响应式系统的变化以及其他API的更新等内容。
|
关系型数据库 MySQL Linux
服务器脚本推荐,yum更新阿里镜像源、安装Docker、使用Docker安装MySQL服务
服务器脚本推荐,yum更新阿里镜像源、安装Docker、使用Docker安装MySQL服务
1743 1
|
消息中间件 存储 缓存
如何打造高可用消息队列?一文读懂关键技术
本文由程序员小米分享如何设计高性能、高可用的消息队列。内容涵盖一致性(生产者确认、消费者幂等性、Broker同步)、可用性(数据不丢不重、持久化策略)、分区容错(选举机制、多副本同步)、海量数据处理(消息积压、Topic性能优化)及性能优化(时间轮、零拷贝、IO多路复用、顺序读写、压缩批处理)等方面,旨在确保分布式系统中消息的可靠性、一致性和高性能。
469 0
|
存储 缓存 监控
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(数据更新场景策略和方案分析)
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(数据更新场景策略和方案分析)
540 0