物联网 MQTT 服务质量级别
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~
翻译人:Tnecesoc,该成员来自云+社区翻译社
消息队列遥测传输(MQTT)是一种客户端服务器发布 / 订阅消息传输协议。它轻量,开放,简单,其设计也易于实施。这些特性使其非常适合用于很多情况,包括在网络连接受限的,需要代码长度较小且 / 或网络带宽非常重要的环境里面,例如在机器对机器(M2M)和物联网(IoT)环境中的通信。该协议通过 TCP / IP 或其他能提供有序,无损,双向的连接的网络协议运行。
MQTT支持三种服务质量级别,如上图所示:
最多发送一次(发完就忘),也就是不确认
至少发送一次,需要进行确认
正好发送一次,要进行 4 步握手
QoS(服务质量)定义了服务端(Broker) / 客户端(Client)确保能收到消息的工作或尝试的方式。消息可以以任何 QoS 级别发送,客户端也可以选择以任意 QoS 级别来订阅主题,后者选择的是他们能收到的最高 QoS 级别。
例如,如有消息以 QoS 2 级别发布并且有一客户端以 Qos 0 级别订阅了相应主题,则那一客户端就会以 QoS 0 级别收到该消息。如果有第二个客户端也订阅了相同的主题,但用的是 QoS 2,则它将以 QoS 2 级别收到这一消息。
举另外一个例子,如有一客户端以 QoS 2 订阅了一个主题,并且有一消息以 QoS 0 在相应主题上发布,则客户端将会基于 QoS 0 级别接收这一消息。高级的 QoS 会更可靠,但也会带来更高的延迟,并占用更多的带宽。
每个 QoS 级别的一些细节就如下所示。MQTT 控制数据包内容的表格位于本文的最后部分,用于描述来自每个 QoS 流的控制数据包。
服务质量级别 0
该消息最多只发送一次,或者在通过网络的传送受阻的时候根本不发送。发送的消息不会被保存。如果客户端断开了连接,或者服务端出现了故障,该消息可能就会因此丢失。这也是最快的传输模式。MQTT 协议并没有要求服务器端将 QoS = 0 的发布消息转发给客户端。如果客户端在服务器收到发布的消息时断开了连接,则发布的消息可能会被丢弃,具体取决于服务器。遥测(MQXR)服务不会丢弃以 QoS = 0 发送的消息。它们会被作为非持久消息而保存,且只有在队列管理器停止运作时才会被丢弃。
在 QoS 0 传送协议中:
发送者:必须发送 QoS = 0,DUP = 0 的 PUBLISH 包;
接收者:在接收到 PUBLISH 包的同时也接受消息的所有权。
服务质量级别 1
该消息至少发送一次。如果发送方没有收到确认包,则会再次发送加上 DUP 标志的该消息,直到收到确认包为止。因此,接收者可能会把相同的消息发送好几次,并且也可能把它处理了好几遍。消息必须保存在发送者以及接收者的本地环境里面,直到这一消息被妥善处理为止。接收者在处理完消息后会把消息删掉。如果接收者是个服务端,则它会将把该消息发布给其订阅者作为对消息的处理。如果接收者是客户端,则会将把消息传递给作为订阅者的应用程序作为处理。在消息被删除之后,接收方会向发送方发送确认包。发送方在收到接收方的确认后会删掉保存在发送方的消息。
这个级别可以用于传送例如环境传感器这样的数据。在这种情况下,单个读数的传送失败了也没多大关系,因为传感器很快就会再把读数发送一遍。
在 QoS 1 传送协议中:
发送方:
必须在每次有新的应用消息发布时为其分配一个没被占用的包标识符。
必须发送一个 PUBLISH 包,其中包含 QoS = 1,DUP = 0 的包标识符。
必须将 PUBLISH 数据包视为 “未经确认” 的,直到它收到了接收方发来的,相应的 PUBACK 数据包为止。
一旦发送者收到 PUBACK 包,对应的消息的包标识符就能收回并重用。请注意,当发送方正在等待接收确认时,它可以用不同的包标识符发送更多的 PUBLISH 包。
接收方:
在接受了应用消息的所有权后,必须用包含传入 PUBLISH 包的包标识符的 PUBACK 包来进行响应。
在发送 PUBACK 包后,接收方必须把每一个传入的包含相同包标识符 PUBLISH 包视为一个全新的发布消息,而不管这些发布消息有没有加上 DUP 标志。
服务质量级别 2
该消息始终只发送一次。消息必须存储在发送方和接收方的本地环境中,直到它被妥善处理为止。QoS = 2 是最安全但也是最慢的传输模式。从发送方删掉消息之前,发送方和接收方之间至少需要两次相互的传输。在第一次传输后,接收方就可以开始处理这一消息。在第一次互传中,发送方会发送消息并从接收方拿到对这一消息的确认。如果发送方没有收到确认,则会再次发送加上了 DUP 标志的该消息,直至收到确认。在第二次互传中,发送方通过给接收方发送 PUBREL 消息来告知后者它可以完成对发布的消息的处理了。如果发送方没有收到接收方对 PUBREL 消息的确认,则会把 PUBREL 消息再发一遍,直到收到确认为止。当发送者收到对 PUBREL 消息的确认时,发送者就会删掉它保存的消息。接收者可以在第一或第二次互传的时候处理消息,只要它不把消息又重新处理一遍就可以了。如果接收者是服务端,它会将消息发布给订阅者。如果接收方是客户端,它会将消息传递给作为订阅者的应用程序。最后接收方会向发送方发送处理完成的消息,来表明它已完成了消息的处理。
举例来说,计费系统可以使用这个级别,因为消息的重复或丢失会导致这样的应用产生错误的计费。
在 QoS 2 传送协议中:
发送方:
必须在每次有新的应用消息发布时为其分配一个没被占用的包标识符。
必须发送一个包含 QoS = 2,DUP = 0 的包标识符的 PUBLISH 包。
必须将 PUBLISH 数据包视为 “未经确认” 的,直到它收到了接收方发来的,相应的 PUBREC 数据包为止。
当它从接收器收到一个 PUBREC 包时,必须发送一个 PUBREL 包。这个 PUBREL 包应该包含与原始 PUBLISH 分组相同的包标识符。
必须将 PUBREL 数据包视为 “未经确认” 的,直到它从接收方收到了相应的 PUBCOMP 包为止。
一旦发送了相应的 PUBREL 包,发送方就不能再发送原始的 PUBLISH 包。一旦发送者收到 PUBCOMP 包,包标识符就可以收回并重用。注意,当发送方正在等待接收确认时,它可以使用不同的包标识符发送更多的 PUBLISH 包。
接收方:
在接受了 PUBLISH 包的应用消息的所有权后,必须用包含传入 PUBLISH 包的包标识符的 PUBREC 包来进行响应。
在接收方收到相应的 PUBREL 包之前,它必须对每一个具有和传入 PUBLISH 包相同包标识符的后续 PUBLISH 包发送一个 PUBREC 包来进行确认。它绝不能容许把一个内容重复的消息传给任何位于下游的接收方。
在收到发送方发来的 PUBREL 包之后,它必须通过发送包含与 PUBREL 相同的包标识符的 PUBCOMP 包来响应。
发送 PUBCOMP 包后,接收方必须把任何后续的具有与传入 PUBLISH 包相同包标识符的后续 PUBLISH 包视为全新的发布消息。
MQTT 控制数据包的详述
控制包 | 发送方向 | 描述 |
---|---|---|
CONNECT | 客户端 -> 服务端 | 客户端请求与服务端建立连接 |
CONNACK | 服务端 -> 客户端 | 连接成功建立 |
PUBLISH | 客户端 -> 服务端 / 服务端 -> 客户端 | 发布消息 |
PUBACK | 客户端 -> 服务端 / 服务端 -> 客户端 | 收到发布消息的确认 |
PUBREC | 客户端 -> 服务端 / 服务端 -> 客户端 | 收到发布消息(Qos 2 的第二次握手) |
PUBREL | 客户端 -> 服务端 / 服务端 -> 客户端 | 不再发布消息(Qos 2 的第三次握手) |
PUBCOMP | 客户端 -> 服务端 / 服务端 -> 客户端 | 消息发布的完结(Qos 2 的第四次握手) |
SUBSCRIBE | 客户端 -> 服务端 | 客户端请求订阅某主题 |
SUBACK | 服务端 -> 客户端 | 订阅操作成功 |
UNSCBSCRIBE | 客户端 -> 服务端 | 客户端请求取消订阅某主题 |
UNSCBACK | 服务端 -> 客户端 | 取消订阅操作成功 |
PINGREQ | 客户端 -> 服务端 | PING 请求 |
PINGRESP | 服务端 -> 客户端 | PING 响应 |
DISCONNECT | 客户端 -> 服务端 | 客户端断开了与服务端的连接 |
参考文献
OASIS 文档:
有些内容转自 BB Smartworx 和 IBM Developer Work。
本文的版权归 Tnecesoc 所有,如需转载请联系作者。
问答
相关阅读
物联网 MQTT 服务质量级别的更多相关文章
- 物联网MQTT协议分析和开源Mosquitto部署验证
在<物联网核心协议—消息推送技术演进>一文中已向读者介绍了多种消息推送技术的情况,包括HTTP单向通信.Ajax轮询.Websocket.MQTT.CoAP等,其中MQTT协议为IBM制定 ...
- Paho -物联网 MQTT C Cient的实现和详解
概述 在文章Paho - MQTT C Cient的实现中,我介绍了如何使用Paho开源项目创建MQTTClient_pulish客户端.但只是简单的介绍了使用方法,而且客户端的结果与之前介绍的并 ...
- 纯vue3实现的svg可视化web组态编辑器。主要用于物联网mqtt实时系统图
vue就是边做这个项目边学的 代码可能有点乱 还望各位大神勿喷 如果代码对您有帮助 麻烦辛苦帮我点个star 预览地址 https://svg.yaolunmao.top 如何使用 # 克隆项目 gi ...
- MQTT物联网通讯协议入门
目录 一.MQTT协议概念 发布/订阅机制 MQTT客户端 Broker代理(服务器) MQTT消息结构 二.MQTT协议实现原理 MQTT连接 MQTT消息发布 MQTT订阅机制 MQTT订阅确认 ...
- 转战物联网·基础篇06-深入理解MQTT协议之基本术语
通过上一节我们对MQTT协议已经有了初步的印象,这一节我们开始深入的理解一下MQTT协议,介绍常用的MQTT 3.1.1版本,5.0版本后面指介绍新增部分即可.这一节我们先介绍MQTT里常用的术语 ...
- MQTT初始篇笔记整理
MQTT简介 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输),基于TCP/IP 协议栈而构建,虽然叫消息队列遥测传输,但是她与消息队列毫无关系,她 ...
- 基于 WebSocket 的 MQTT 移动推送方案
WebSphere MQ Telemetry Transport 简介 WebSphere MQ Telemetry Transport (MQTT) 是一项异步消息传输协议,是 IBM 在分析了他们 ...
- 国外物联网平台(3):IBM Watson IoT
国外物联网平台(3)——IBM Watson IoT 马智 平台定位 提供全面管理的云托管服务,旨在简化并从 IoT 设备中获得价值. Watson IoT Platform 提供对 IoT 设备和数 ...
- MQTT 协议是个啥?这篇文章告诉你!
文章首发于我的公众号「程序员cxuan」,欢迎大家关注呀- 说到做到! 之前有位读者给我留言说想要了解一下什么是 MQTT 协议,顺便还把我夸了一把,有点不好意思啦. 那么读者的要求必须要满足啊,所以 ...
随机推荐
- django “如何”系列4:如何编写自定义模板标签和过滤器
django的模板系统自带了一系列的内建标签和过滤器,一般情况下可以满足你的要求,如果觉得需更精准的模板标签或者过滤器,你可以自己编写模板标签和过滤器,然后使用{% load %}标签使用他们. 代码 ...
- 蚂蚁金服安全实验室首次同时亮相BlackHat Asia 以及CanSecWest国际安全舞台
近期,蚂蚁金服巴斯光年安全实验室(以下简称AFLSLab)同时中稿BlackHat Asia黑帽大会的文章以及武器库,同时在北美的CanSecWest安全攻防峰会上首次中稿Android安全领域的漏洞 ...
- 关于换了手机后,导致原来连的fiddler抓不到新手机上的包的解决方法
原来我们测试都是一台安卓机,一台ios机,由于机子不够,所以安卓机都是自己的手机,可以连内网,也可以连外网 但是最近这几天,不知道公司抽了什么风.把网都给限制了,只有公司的测试机,才能连内网测,结果我 ...
- python中functools.singledispatch的使用
from functools import singledispatch @singledispatch def show(obj): print (obj, type(obj), "obj ...
- NetFPGA-1G-CML Demo --- reference_router_nf1_cml
环境 deepin 15.4 vivado 15.2 ise 14.6 前期准备 Github Wiki链接:https://github.com/NetFPGA/NetFPGA-public/wik ...
- 手把手教你 LabVIEW 串口仪器控制——VISA 驱动下载安装篇
仪器控制,核心在于 VISA 函数..有些仪器可能不需要 VISA,有自己的 DLL 什么的,我就管不着. 正常情况下,大家安装的 LabVIEW,都是不带 VISA 驱动 ...
- istio入门(00)istio的学习资源
官网:https://istio.io/ 理论知识: http://www.uml.org.cn/wfw/201710131.asp 环境搭建: http://dockone.io/article/2 ...
- javascript学习(2)修改html元素和提示对话框
一.修改html元素 1.修改p元素 1.1.源代码 1.2.执行前 1.3.执行后 2.修改div元素的className 2.1.源代码 1.2.执行前 1.3.执行后 3.直接在当前位置输出内容 ...
- linux下的Shell编程(7)使用-x和-n调试shell程序
我们也可以在Shell下调试Shell Script脚本,当然最简单的方法就是用echo输出查看变量取值了.Bash也提供了真正的调试方法,就是执行脚本的时候用-x参数. sh -x filename ...
- JS解析JSON字符串
问题描述:后台需要传递给前台一些数据,用于页面数据显示,因为是一些Lable标签,所以数据传递到前台需要解析. 思路:因为数据比较杂乱,所以我选择传递的数据类型是Json格式,但是数据展示时需要解析成 ...