MQTT Qos详解(一)
本文基于标准MQTT讨论,不适合其他对MQTT机制做了修改的非标准MQTT协议。
MQTT设计了一套保证消息稳定传输的机制,包括消息应答、存储和重传。在这套机制下,提供了三种不同层次QoS(Quality of Service):
- QoS0,发送就不管了,最多一次;
- QoS1,发送之后依赖MQTT规范,是否启动重传消息,所以至少一次;
- QoS2,发送之后依赖MQTT消息机制,确保只有一次。
QoS 是消息的发送方(Sender)和接受方(Receiver)之间达成的一个协议:(MQTT不是端到端的通信)
- QoS0 代表,Sender 发送的一条消息,Receiver 最多能收到一次,也就是说 Sender 尽力向 Receiver 发送消息,如果发送失败,也就算了;这是完全依赖TCP重传机制,如果网络不好,TCP的重传也不是100%可靠,加上MQTT是Publisher 发出去的消息是依赖代理服务器完成转发,所以消息最多一次。
- QoS1 代表,Sender 发送的一条消息,Receiver 至少能收到一次,也就是说 Sender 向 Receiver 发送消息,如果发送之后没有收到对应的PUBACK,就会继续重试,直到发送者Sender 接收到 Receiver 发送的 PUBACK 为止,因为重传的原因,Receiver 有可能会收到重复的消息;
- QoS2 代表,Sender 发送的一条消息,Receiver 确保能收到而且只收到一次,也就是说 Sender 尽力向 Receiver 发送消息,如果发送失败,会继续重试,直到 Receiver 收到消息为止,同时保证 Receiver 不会因为消息重传而收到重复的消息。(个人理解这一点有点像TCP三次握手的交互过程)
下面讨论Qos不降级的情况,即订阅者与发布者的Qos等级相同。
Qos 0的交互流程:
- 消息的分发依赖于底层网络的能力。接收者不会发送响应,发送者也不会重试。消息可能送达一次也可能根本没送达。消息从Publisher发送给代理服务broker,或者broker发送给Subscriher,都可能会丢失。
注意:对于QoS 0的消息, DUP标志必须设置为0
Qos 1的交互流程:
只有当QoS等级是1或2时, 报文标识符( Packet Identifier) 字段才能出现在PUBLISH报文中。下面是MQTT Qos的补充说明:
[MQTT-4.3.2-1] 对于QoS 1的分发协议, 发送者
- 每次发送新的应用消息都必须分配一个未使用的报文标识符。
- MUST send a PUBLISH Packet containing this Packet Identifier with QoS=1,DUP=0。
- 发送的PUBLISH报文必须包含报文标识符且QoS等于1,DUP等于0。
- 必须将这个PUBLISH报文看作是 未确认的 , 直到从接收者那收到对应的PUBACK报文。 4.4节有一个关于未确认消息的讨论。
[MQTT-4.3.2-2] 对于QoS 1的分发协议, 接收者
- 响应的PUBACK报文必须包含一个报文标识符,这个标识符来自接收到的、已经接受所有权的PUBLISH报文。
- 发送了PUBACK报文之后,接收者必须将任何包含相同报文标识符的入站PUBLISH报文,当作一个新的消息, 并忽略它的DUP标志的值。
- Sender 向 Receiver 发送一个带有消息数据的 PUBLISH 包, 并在本地保存这个 PUBLISH 包。
- Receiver 收到 PUBLISH 包以后,向 Sender 发送一个 PUBACK 数据包,PUBACK 数据包没有消息体(Payload),在可变头中(Variable header)中有一个包标识(Packet Identifier),和它收到的 PUBLISH 包中的报文标识符(Packet Identifier) 一致。
- Sender 收到 PUBACK 之后,根据 PUBACK 包中的 Packet Identifier 找到本地保存的 PUBLISH 包,然后丢弃掉,一次消息的发送完成。
- 如果 Sender 在一段时间内没有收到 PUBLISH 包对应的 PUBACK,它将该 PUBLISH 包的 DUP 标识设为 1(代表是重新发送的 PUBLISH 包),然后重新发送该 PUBLISH 包。重复这个流程,直到收到 PUBACK,然后执行第 3 步。
注意:Qos 1代理服务器是不会进行去重的,只要发布者或者代理服务器没有收到PUBACK,就认为主题消息没有发送成功进入重发,代理服务器或者订阅者,不会根据dup的值进行去重。
换句话说,代理服务器(broker)或者订阅者(Subscriber)在发送PUBACK报文时,(Publisher 者)发布消息主题的程序或者代理服务器(broker)的程序,已经对PUBACK报文做了判断,那么还是会重发该主题消息,并且dup标志位会+1,这样订阅者或者代理服务器就会收到多份重复的消息。并且不会去重!
Qos 2的交互流程:
只有当QoS等级是1或2时, 报文标识符( Packet Identifier) 字段才能出现在PUBLISH报文中,另外QoS 2在消息头有Message ID。下面是补充说明
[MQTT-4.3.3-1] 对于QoS 2的分发协议, 发送者
1、必须给要发送的新应用消息分配一个未使用的报文标识符。
- MUST send a PUBLISH packet containing this Packet Identifier with QoS=2,DUP=0。
2、发送的PUBLISH报文必须包含报文标识符且报文的QoS等于2,DUP等于0。
必须将这个PUBLISH报文看作是 未确认的 , 直到从接收者那收到对应的PUBREC报文。 4.4节有一个关于未确认消息的讨论。
收到PUBREC报文后必须发送一个PUBREL报文。 PUBREL报文必须包含与原始PUBLISH报文相同的报文标识符。
必须将这个PUBREL报文看作是 未确认的 , 直到从接收者那收到对应的PUBCOMP报文。
一旦发送了对应的PUBREL报文就不能重发这个PUBLISH报文。
[MQTT-4.3.3-2] 对于QoS 2的分发协议, 接收者
- 响应的PUBREC报文必须包含报文标识符, 这个标识符来自接收到的、 已经接受所有权的PUBLISH报文。
- 在收到对应的PUBREL报文之前, 接收者必须发送PUBREC报文确认任何后续的具有相同标识符的PUBLISH报文。 在这种情况下, 它不能重复分发消息给任何后续的接收者。
- 响应PUBREL报文的PUBCOMP报文必须包含与PUBREL报文相同的标识符。
发送PUBCOMP报文之后, 接收者必须将包含相同报文标识符的任何后续PUBLISH报文当作一个新的发布。
- Sender 发送 QoS 为 2 的 PUBLISH 数据包,数据包包含报文标识符:Packet Identifier ,并在本地保存该 PUBLISH 包;
- Receiver (代理服务器或者订阅者)收到 PUBLISH 数据包以后,在本地保存 PUBLISH 包,并回复 Sender 一个 PUBREC 数据包,PUBREC 数据包可变头中的 报文标识符(Packet Identifier) 与 Sender 发送的报文标识符(Packet Identifier)一致,但是没有消息体(Payload);
- 当 Sender 收到 PUBREC,它就可以安全地丢弃掉初始发送的PUBLISH包,同时保存该 PUBREC 数据包,同时回复 Receiver 一个 PUBREL 数据包,PUBREL 数据包可变头中的报文标识符(Packet Identifier)保持不变,同样没有消息体(Payload);
- 如果 Sender 在一定时间内没有收到 PUBREC,它会把 PUBLISH 包的重发标志位 DUP 标识设为 1,重新发送该 PUBLISH 数据包(Payload);(在第三步和第四步之间是可能存在消息重传的)
- 当 Receiver 收到 PUBREL 数据包,它可以丢弃掉保存的 PUBLISH 包,并回复 Sender 一个 PUBCOMP 数据包,PUBCOMP 数据包可变头中的报文标识符(Packet Identifier)保持不变,没有消息体(Payload);
- 当 Sender 收到 PUBCOMP 包,那么它认为数据包传输已完成,它会丢弃掉对应的 PUBREC 包。如果 Sender 在一定时间内没有收到 PUBCOMP 包,它会重新发送 PUBREL 数据包。
注意:
- 1.Qos 2代理服务器是不会进行去重的,只要发布者或者代理服务器,没有收到PUBREC,就认为主题消息没有发送成功进入重发,代理服务器或者订阅者,不会根据dup的值进行去重。这一步会有去重,保证收到主题消息的唯一性。
- 发送者或者代理服务器,收到PUBREC,就认为主题消息已经发送出去,不会进行重复发送;至于订阅者,MQTT会控制显示消息,如果收到了PUBREL就认为消息已经收到,只需要在发送PUBCOMP,完成MQTT Qos 2 的交互流程。
总结:
在Qos 1 情况下,如果PUBACK超时或者发送失败,就会重传消息;
在Qos 2情况下,在没有收到PUBREC之前,也是有消息重传的可能,但是在接收到PUBREC报文之后,主题消息被删除,这样就不会对下面的交互过程产生干扰,消息在这一步之后,只能重传PUBREC、PUBREL报文。
MQTT Qos详解(一)相关推荐
- MQTT QoS 详解
本文主要介绍 MQTT 协议中 QoS(服务质量) 的详细内容. 1.概述 MQTT 协议 中规定了消息服务质量(Quality of Service),它保证了在不同的网络环境下消息传递的可靠性,Q ...
- IoT:MQTT协议详解
IoT -- (七)MQTT协议详解 转自:https://blog.csdn.net/anxianfeng55555/article/details/80908795 MQTT是什么? MQTT(M ...
- MQTT协议详解 三、MQTT控制包(CONNECT)
文章目录 系列文章目录 前言 CONNECT(客户端请求连接服务端) 一.固定包头(2字节) 二.可变包头(10字节) 协议名字(6字节) 协议等级(1字节) 连接标识(1字节) Clean Sess ...
- MQTT协议详解 二、MQTT控制包格式
文章目录 系列文章目录 前言 一.MQTT控制包格式 二.固定包头 控制包类型 控制包类型标识 剩余长度 三.可变包头 数据包标识 四.载荷 系列文章目录 MQTT协议详解 一.MQTT简介 MQTT ...
- MQTT协议详解,非常易懂
MQTT协议详解一 协议地址:http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html 当然也有PDF版的,百度 ...
- MQTT协议详解 一、MQTT简介
文章目录 系列文章目录 前言 一.简述 二.主要特性 三.应用领域 四.常见术语 总结 系列文章目录 MQTT协议详解 一.MQTT简介 MQTT协议详解 二.MQTT控制包格式 MQTT协议详解 三 ...
- MQTT协议详解及v5.0实践——实践类
本文主要包含了以下内容: 1)MQTT协议演进历史及协议特点,总结和分析MQTT协议族的优缺点,分析和总结了为什么相比于其他协议,MQTT适合IoT,业内支持现状等. 2)阿里云IoT MQTT3和5 ...
- MQTT协议详解及开发教程(四)MQTT协议报文格式
推荐一款稳定的基于C编写的MQTT Client开源库 cMQTT MQTT协议详解及开发教程(一)MQTT协议概述 MQTT协议详解及开发教程(二)MQTT服务器EMQx搭建 MQTT协议详解及开发 ...
- http发送16进制报文_阿里云物联网平台使用心得(25)MQTT协议详解UNSUBSCRIBE报文...
题目 大家好,超子又和大家见面了,超子我能力有限,水平不高,有什么错误的地方,欢迎板砖.超子今天给大家介绍一下UNSUBSCRIBE报文. UNSUBSCRIBE报文 从上图中可知,UNSUBSCRI ...
- mqtt协议详解_IoT物联网设备上云技术方案详解
随着传感器和通信技术的不断发展,物联网行业方兴未艾,业务链路涉及数据采集,通信连接,数据存储,数据可视化,洞察,行动决策.但,在实施过程中,碎片化的设备端通信连接难题往往就阻碍了项目落地进程. 今天, ...
最新文章
- vue2.0组件之间的通信
- C# indexof和indexofany区别(转)
- 深度学习核心技术精讲100篇(十七)-多标准中文分词( Multi-Criteria-CWS)
- 【Git】认识各种开源协议及其关系
- 带你了解2020年全新【思科专家级认证CCIE】
- apache启动失败_请检查相关配置.√mysql5.1已启动._1、Apache启动失败,请检查相关配置-百度经验...
- LAMP环境中Apache,MySQL,PHP的配置文件路径是什么
- 张宇基础30讲——第6讲-中值定理
- 为 Vue 项目添加 cnzz 统计
- IPv4地址--公网地址可以有多少
- Android缓存,删除网络依赖包缓存
- RAR Extractor - The Unarchiver Pro for mac(解压缩软件)
- 超详细的WMS仓储管理系统介绍——补货篇
- 【信管2.6】项目可研(二)详细可行性研究
- 最方便的ICON、PNG转换工具
- leetcode【51-52】N-Queens N-Queens II
- 潮汕牛肉丸是熟的还是生的 潮汕牛肉生丸和熟丸区别
- 智慧高速公路车路协同系统框架及要求第二部分
- 关于分贝dB的理解与电子学的关系
- 总结整理时下流行的浏览器User-Agent大全
热门文章
- go reflection
- SpringBoot 发送邮件功能(包含网易、QQ、Gmail邮箱)
- matlab蒙特卡洛模拟几何布朗,【数值模拟】几何布朗运动数值解的模拟
- 雷石服务器可以接入电视信号吗,雷石机顶盒使用方法
- jmeter.results.shanhe.me.xsl
- python中集合用什么符号表示_Python 集合set添加删除、交集、并集、集合操作符号...
- JAVA图片加水印(电子奖状填充名字)
- WinDbg单机调试
- 以计算机为主题的想象作文,以想象为话题的作文(通用13篇)
- 一篇文章看明白 TCP/IP,TCP,UDP,IP,Socket 之间的关系