当前位置: 首页 > news >正文

解密MQTT协议:从QOS到消息传递的全方位解析

1、QoS介绍

1.1、QoS简介

使用MQTT协议的设备大部分都是运行在网络受限的环境下,而只依靠底层的TCP传输协议,并不

能完全保证消息的可靠到达。

MQTT提供了QoS机制,其核心是设计了多种消息交互机制来提供不同的服务质量,来满足用

户在各种场景下对消息可靠性的要求。

MQTT 定义了三个 QoS 等级,分别为:

1、QoS 0,最多交付一次 -----> 可能丢失消息

2、QoS 1,至少交付一次 -----> 可以保证收到消息,但消息可能重复

3、QoS 2,只交付一次 -----> 可以保证消息既不丢失也不重复

QoS等级是由发布者在PUBLISH报文中指定的,大部分情况下Broker向订阅者转发消息时都会维

持原始的 QoS 不变。不过也有一些例外的情况,根据订阅者的订阅要求,

消息的 QoS 等级可能会在转发的时候发生降级。

例如,订阅者在订阅时要求Broker可以向其转发的消息的最大QoS等级为QoS 1,那么后续所有

QoS 2消息都会降级至QoS 1转发给此订阅者,而所有QoS 0和QoS 1消息

则会保持原始的QoS等级转发。

1.2、QoS 0原理介绍

1.2.1、通讯原理说明

QoS 0 是最低的 QoS 等级。QoS 0 消息即发即弃,不需要等待确认,不需要存储和重传,因此对

于接收方来说,永远都不需要担心收到重复的消息。

涉及到的相关报文:

1.2.2、Qos 0消息丢失原因

当我们使用 QoS 0 传递消息时,消息的可靠性完全依赖于底层的 TCP 协议。而 TCP 只能保证在

连接稳定不关闭的情况下消息的可靠到达,一旦出现连接关闭、重置,

仍有可能丢失当前处于网络链路或操作系统底层缓冲区中的消息。这也是 QoS 0 消息最主要的丢

失场景。

1.3、Qos 1原理介绍

1.3.1、通讯原理说明

为了保证消息到达,QoS 1 加入了应答与重传机制,发送方只有在收到接收方的 PUBACK 报文以

后,才能认为消息投递成功,在此之前,发送方需要存储该 PUBLISH 报文以便下次重传。

QoS 1需要在 PUBLISH 报文中设置 Packet ID,而作为响应的 PUBACK 报文,则会使用与

PUBLISH 报文相同的 Packet ID,以便发送方收到后删除正确PUBLISH报文缓存。

涉及到的相关报文:

1.3.2、Qos 1消息会重复原因

对于发送方来说,没收到 PUBACK 报文分为以下两种情况:

1、PUBLISH 未到达接收方

2、PUBLISH 已经到达接收方,接收方的 PUBACK 报文还未到达发送方

在第一种情况下,发送方虽然重传了 PUBLISH 报文,但是对于接收方来说,实际上仍然仅收到了

一次消息。

在第二种情况下,在发送方重传时,接收方已经收到过了这个 PUBLISH 报文,这就导致接收方将

收到重复的消息。

重传 PUBLISH 报文的时候,PUBLISH 中的 DUP 标志会被设置为 1,用以表示这是一个重传的报

文。

1.4、Qos 2原理介绍

1.4.1、通讯原理说明

QoS 2 解决了 QoS 0、1 消息可能丢失或者重复的问题,但相应地,它也带来了最复杂的交互流程

和最高的开销。每一次的 QoS 2 消息投递,都要求发送方与接收方进行至少两次请求/响应流

流程说明:

1、首先,发送方存储并发送 QoS 为 2 的 PUBLISH 报文以启动一次 QoS 2 消息的传输,然后等

待接收方回复 PUBREC 报文。这一部分与 QoS 1 基本一致,只是响应报文从 PUBACK 变成了

PUBREC。

2、当发送方收到 PUBREC 报文,即可确认对端已经收到了 PUBLISH 报文,发送方将不再需要重

这个报文,并且也不能再重传这个报文。所以此时发送方可以删除本地1存储的 PUBLISH 报

文,然后发送一个 PUBREL 报文,通知对端自己准备将本次使用的 Packet ID 标记为可用了。与

PUBLISH 报文一样,我们需要确保 PUBREL报文到达对端,所以也需要一个响应报文,并且这个

PUBREL 报文需要被存储下来以便后续重传。

3、当接收方收到 PUBREL 报文,也可以确认在这一次的传输流程中不会再有重传的 PUBLISH 报

文到达,因此回复 PUBCOMP 报文表示自己也准备好将当前的 PacketID 用于新的消息了。

4、当发送方收到 PUBCOMP 报文,这一次的 QoS 2 消息传输就算正式完成了。在这之后,发送

方可以再次使用当前的 Packet ID 发送新的消息,而接收方再次收到使用这个 Packet ID 的

PUBLISH 报文时,也会将它视为一个全新的消息。

涉及到的报文:

1.4.2、Qos 2消息不会重复原因

消息不丢失原因:与 QoS 1 相同

消息不会重复原因:

快速回顾一下 QoS 1 消息无法避免重复的原因:

当我们使用 QoS 1 消息时,对接收方来说,回复完 PUBACK 这个响应报文以后 Packet ID 就重新

可用了,也不管响应是否确实已经到达了发送方。所以就无法得知之后到达的,携带了相同

Packet ID 的 PUBLISH 报文,到底是发送方因为没有收到响应而重传的,还是发送方因为收到了

响应所以重新使用了这个 Packet ID 发送了一个全新的消息。

所以,消息去重的关键就在于,通信双方如何正确地同步释放 Packet ID,换句话说,不管发送方

是重传消息还是发布新消息,一定是和对端达成共识了的。而 QoS 2中增加的 PUBREL 流程,正

是提供了帮助通信双方协商 Packet ID 何时可以重用的能力。

QoS 2 规定,发送方只有在收到 PUBREC 报文之前可以重传 PUBLISH 报文。一旦收到 PUBREC 报

文并发出 PUBREL 报文,发送方就进入了 Packet ID 释放流程,不可以再使用当前 Packet ID 重

传 PUBLISH 报文。同时,在收到对端回复的 PUBCOMP 报文确认双方都完成 Packet ID 释放之

前,也不可以使用当前Packet ID 发送新的消息。

因此,对于接收方来说,能够以 PUBREL 报文为界限,凡是在 PUBREL 报文之前到达的

PUBLISH 报文,都必然是重复的消息;而凡是在 PUBREL 报文之后到达的

PUBLISH 报文,都必然是全新的消息。一旦有了这个前提,我们就能够在协议层面完成 QoS 2 消

息的去重。

相关文章:

解密MQTT协议:从QOS到消息传递的全方位解析

1、QoS介绍 1.1、QoS简介 使用MQTT协议的设备大部分都是运行在网络受限的环境下,而只依靠底层的TCP传输协议,并不 能完全保证消息的可靠到达。 MQTT提供了QoS机制,其核心是设计了多种消息交互机制来提供不同的服务质量,来满足…...

Java-02 深入浅出 MyBatis - MyBatis 快速入门(无 Spring) POM Mapper 核心文件 增删改查

点一下关注吧!!!非常感谢!!持续更新!!! 大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了: MyBatis&#xff…...

Unity功能模块一对话系统(4)实现个性文本标签

本期我们将了解如何在TMPro中自定义我们的标签样式&#xff0c;并实现两种有趣的效果。 一.需求描述 1.定义<float>格式的标签&#xff0c;实现标签处延迟打印功能 2.定义<r" "></r>格式的标签&#xff0c;实现标签区间内文本片段的注释显示功能…...

git在idea中操作频繁出现让输入token或用户密码,可以使用凭证助手(使用git命令时输入的用户密码即可) use credential helper

1、打开 idea 设置&#xff0c;找到 git 路径 File | Settings | Version Control | Git 2、勾选 Use credential helper 即可...

毫米波雷达技术:(九)快时间窗和慢时间窗的概念

&#xff08;一&#xff09;快时间窗&#xff1a; 快时间窗通常指的是在雷达脉冲周期内&#xff0c;对每个脉冲回波进行采样的时间段。这个时间段非常短&#xff0c;通常在 0 − 100 n s 0-100ns 0−100ns 。在快时间窗内&#xff0c;雷达系统会对接收到的回波信号进行高分辨…...

宠物行业的出路:在爱与陪伴中寻找增长新机遇

在当下的消费市场中&#xff0c;如果说有什么领域能够逆势而上&#xff0c;宠物行业无疑是一个亮点。当人们越来越注重生活品质和精神寄托时&#xff0c;宠物成为了许多人的重要伴侣。它们不仅仅是家庭的一员&#xff0c;更是情感的寄托和生活的调剂。然而&#xff0c;随着行业…...

Android MQTT关于断开连接disconnect报错原因

最近项目遇到一个需求&#xff0c;就是在登录状态的时候。才能接收到消息。所有我在上线&#xff0c;下线状态的时候。做了MQTT断开和连接的动作。然后就是发生了。我们标题的这关键点了。直接报错了。报错的内容如下&#xff1a; MqttAndroidClient unregisterRecevicer afte…...

Unity3D中Huatuo可行性的思维实验详解

引言 Unity3D作为一款功能强大的跨平台游戏引擎&#xff0c;在游戏开发领域具有举足轻重的地位。它不仅支持2D和3D游戏开发&#xff0c;还广泛应用于虚拟现实、建筑可视化等领域。其中&#xff0c;Huatuo作为一个强大的热更新解决方案&#xff0c;通过扩展Unity的IL2CPP运行时…...

ES-聚合分析

ES的聚合分析 什么是ES的聚合分析 ElasticSearch除搜索意外&#xff0c;提供的针对ES数据进行统计分析的功能通过聚合&#xff0c;我们会得到一个数据的概览&#xff0c;是分析和总结全套的数据&#xff0c;而不是寻找单独的文档高性能&#xff0c;只要一条语句就可以得到分析…...

【CSS in Depth 2 精译_093】16.2:CSS 变换在动效中的应用(上)—— 图标的放大和过渡效果的设置

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第五部分 添加动效 ✔️【第 16 章 变换】 ✔️ 16.1 旋转、平移、缩放与倾斜 16.1.1 变换原点的更改16.1.2 多重变换的设置16.1.3 单个变换属性的设置 16.2 变换在动效中的应用 ✔️ 16.2.1 放大图…...

Linux Debian安装ClamAV和命令行扫描病毒方法,以及用Linux Shell编写了一个批量扫描病毒的脚本

ClamAV是一个开源的跨平台病毒扫描引擎&#xff0c;用于检测恶意软件、病毒、木马等安全威胁。 一、Linux Debian安装ClamAV 在Linux Debian系统上安装ClamAV&#xff0c;你可以按照以下步骤进行&#xff1a; 更新软件包列表&#xff1a; 打开终端并更新你的软件包列表&#…...

Spring创建异步线程,使用@Async注解时不指定value可以吗?

在Spring中使用Async注解时&#xff0c;不指定value是可以的。如果没有指定value&#xff08;即线程池的名称&#xff09;&#xff0c;Spring会默认使用名称为taskExecutor的线程池。如果没有定义taskExecutor线程池&#xff0c;则Spring会自动创建一个默认的线程池。 默认行为…...

二分和离散化

为什么把二分和离散化放一起&#xff1a;因为离散化其实是一种二分整数的过程。 二分 相信大家都接触过二分查找&#xff08;折半查找&#xff09;&#xff0c;这就是二分的思想。 二分通过每次舍弃一半并不存在答案的区间&#xff0c;进而快速锁定要求的答案&#xff08;二…...

深度学习实战102-基于深度学习的网络入侵检测系统,利用各种AI模型和pytorch框架实现网络入侵检测

大家好,我是微学AI,今天给大家介绍一下深度学习实战102-基于深度学习的网络入侵检测系统,利用各种AI模型和pytorch框架实现网络入侵检测。近年来,网络安全威胁日益严峻,传统基于规则的方法难以应对复杂多变的入侵手段。 深度学习技术凭借其强大的特征学习能力和自适应性,…...

vue3使用element-plus,解决 el-table 多选框,选中后翻页再回来选中失效问题

问题&#xff1a;勾选的数据分页再回来回消失 1.在el-table中加 :row-key"getRowKey" const getRowKey (row) > { return row.id; // id必须是唯一的 }; 2.给type为selection的el-table-column添加上reserve-selection属性 <el-tableref"multipleTab…...

网络的类型

BMA---广播型多路访问--在一个网段内可以放置多个物理节点,同时该范围内可以实施广播洪泛机制 【1】以太网-->共享型 属性典型的 BMA类型;以太网技术的核心为频分一在同一物理介质上&#xff0c;使用多个相互不干涉的频率电波来共同传输数据&#xff0c;实现带宽的不断提升…...

实现类似gpt 打字效果

1. css的动画&#xff08;animation) css中实现动画有两种方式&#xff1a;transition过渡动画、 animation自定义动画。 具体的可以看MDN链接&#xff1a;https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation 使用keyframes自定义关键帧动画并未其命名使用自定义动…...

项目需求分析流程

项目需求分析是软件开发或任何工程项目中至关重要的第一步。它帮助确保团队理解客户的需求&#xff0c;并为后续的设计、开发和测试工作提供指导。以下是一个详细的需求分析流程&#xff1a; 一、确定项目目标 与利益相关者沟通&#xff1a;包括但不限于客户、最终用户、销售…...

idea连接SQL Server数据库_idea连接sqlserver数据库

4.设置密码&#xff08;这一步可以在安装数据库时就可以完成&#xff09;&#xff0c;如果觉得用户名有问题&#xff0c;也可以修改用户名 5.查看SQL Server端口号&#xff08;默认端口&#xff1a;1433&#xff09;&#xff0c;选择SQL Server2019配置管理器 6.打开SQL Server…...

Scala_【2】变量和数据类型

第二章 注释标识符的命名规范命名规则关键字 变量字符串输出数据类型关系变量和数据类型整数类型&#xff08;Byte、Short、Int、Long&#xff09;浮点类型&#xff08;Float、Double&#xff09;字符类型&#xff08;Char&#xff09;布尔类型&#xff08;Boolean&#xff09;…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中&#xff0c;return 语句的使用是另一个关键概念&#xff0c;它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别&#xff1a;不同层级的事件处理 方…...

快速排序算法改进:随机快排-荷兰国旗划分详解

随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...