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

MQTT协议规范总结

MQTT架构

一、版本介绍:

1、MQTT V3.1.1-2014年

  MQTT v3.1.1 是 MQTT 的第一个 OASIS 标准版本,ISO/IEC 20922:2016

2、MQTT V5.0--2019年

MQTT v5.0 在保留很多核心功能的基础上添加了大量新的功能,主要功能目标是:

  • 增强了扩展性以及大型扩展系统。
  • 改善了错误报告。
  • 形式化了一些通用范式,包括功能发现(capability discovery)和请求响应。
  • 多了扩展机制,包括用户属性(user properties)
  • 性能改进以及对小客户端的支持

对比两个版本无较大的改动,下面对一些常用的术语和参数总结

二、相关术语

 网络连接(Network Connection)、应用消息(Application Message)、客户端( Client)、服务端(Server)、会话(Session )、订阅(Subscription)、共享订阅(Shared Subscription)、通配符订阅(Wildcard Subscription )、主题名(Topic Name)、主题过滤器(Topic Filter)、控制报文(MQTT Control Packet)、协议错误(Protocol Error)、畸形报文(Malformed Packet )、遗嘱消息(Will Message )

 应用消息(Application Message

   MQTT协议通过网络传输应用数据。应用消息通过MQTT传输时,它们包含有效载荷数据(Payload Data),服务质量(QoS),一套属性(Properties)的集合和主题名(Topic Name)

 有效载荷数据:

  包含一个或多个以长度为前缀的字段,可变报头中的标志决定是否包含这些字段。如果包含的话,必须按这个顺序出现:客户端标识符,遗嘱属性,遗嘱主题,遗嘱消息,遗嘱有效负载,用户名,密码 [MQTT-3.1.3-1]

 客户端( Client

 使用MQTT的程序或设备

 服务端(Server

 一个程序或设备,作为发送消息的客户端和请求订阅的客户端之间的中介,例如转发服务器EMQx

会话(Session )

 客户端和服务端之间的状态交互,一些会话持续时长和网络连接一样,另一些会话可以在客户端和服务端之间扩展多个连续的网络连接

 订阅(Subscription

 订阅包含一个主题过滤器(Topic Filter)和一个最大的服务质量(QoS)等级。订阅与单个会话(Session)关联。会话可以包含多于一个的订阅。会话的每个订阅都有一个不同的主题过滤器

 主题名(Topic Name

 附加在应用消息上的一个标签,服务端已知且与订阅匹配

 控制报文(MQTT Control Packet

 通过网络连接发送的信息数据包。MQTT规范定义了十五种不同类型的控制报文,其中一个(PUBLISH报文)用于传输应用消息,其中的15种控制报文如下所述:

CONNECT报文

分固定报头和可变报头

其中可变报头包含协议名(Protocol Name), 协议级别(Protocol Level), 连接标志(Connect Flags)和保持连接(Keep Alive)

连接标志包含:清理会话、遗嘱标志、遗嘱Qos、遗嘱保留、密码标志、用户名标志

连接标志-清理会话标志:

客户端和服务端可以保存会话状态,以支持跨网络连接的可靠消息传输。 这个标志位用于控制会话状态的生存时间
如果清理会话(CleanSession) 标志被设置为 0, 服务端必须基于当前会话(使用客户端标识符识别) 的状态恢复与客户端的通信。 如果没有与这个客户端标识符关联的会话, 服务端必须创建一个新的会话。
如果清理会话(CleanSession) 标志被设置为 1, 客户端和服务端必须丢弃之前的任何会话并开始一个新的会话。会话仅持续和网络连接同样长的时间。 与这个会话关联的状态数据不能被任何之后的会话重用

连接标志-遗嘱标志:

在服务端并且与这个网络连接关联。之后网络连接关闭时,服务端必须发布这个遗嘱消息, 除非服务端收到DISCONNECT 报文时删除了这个遗嘱消息
保持连接(keep alive)

 1)如果保持连接的值非零,并且服务端在一点五倍的保持连接时间内没有收到客户端的控制报文, 它必须断开客户端的网络连接, 认为网络连接已断开

 2)不管保持连接的值是多少,客户端任何时候都可以发送 PINGREQ 报文,并且使用 PINGRESP 报文判断网络和服务端的活动状态

3)客户端发送了 PINGREQ 报文之后, 如果在合理的时间内仍没有收到 PINGRESP 报文, 它应该关闭到服务端的网络连接

4)保持连接的值为零表示关闭保持连接功能。 这意味着,服务端不需要因为客户端不活跃而断开连接。 注意:不管保持连接的值是多少, 任何时候,只要服务端认为客户端是不活跃或无响应的, 可以断开客户端的连接。

保持连接的实际值是由应用指定的, 一般是几分钟。 允许的最大值是 18 小时 12 分 15 秒。
 

其中的Publish报文分为固定报头和可变报头,其中

Publish报文-固定报头

 包含了MQTT控制报文类型(例如PUBLISH报文)、DUP(重发标志)、Qos等级(服务质量等级)、RETAIN(保留标志)、剩余长度

重发标志:

客户端或服务端请求重发一个 PUBLISH 报文时, 必须将 DUP 标志设置为 1,对于 QoS
0 的消息, DUP 标志必须设置为 0

Qos等级

 表示应用消息分发的服务质量等级保证

 RETAIN(保留标志)

如果客户端发给服务端的 PUBLISH 报文的保留(RETAIN) 标志被设置为 1, 服务端必须存储这个应用消息和它的服务质量等级(QoS) ,以便它可以被分发给未来的主题名匹配的订阅者,也即是新的订阅者能够获取到之前设备端最近的状态信息。

剩余长度

 可变报头的长度+有效载荷的长度

Publish报文-可变报头

主题名:用于识别有效载荷数据应该被发布到哪一个信息通道

报文标识符:只有当 QoS 等级是 1 或 2 时,报文标识符(Packet Identifier) 字段才能出现在 PUBLISH 报文中

Publish报文-有效载荷

有效载荷包含将被发布的应用消息。 数据的内容和格式是应用特定的。 有效载荷的长度这样计算: 用固定报头中的剩余长度字段的值减去可变报头的长度。 包含零长度有效载荷的 PUBLISH 报文是合法的

Publish报文-响应

 PUBLISH 报文的接收者必须按照根据 PUBLISH 报文中的 QoS 等级发送响应

 

 协议错误(Protocol Error

  在报文被解析后发现报文包含了协议不允许的数据或者该数据与客户端和服务器的状态不一致

 畸形报文(Malformed Packet )

 无法根据规范解析的控制数据包

 遗嘱消息(Will Message )

 若网络连接关闭或非正常断开, 服务器需要发布的应用消息

 三、关于MQTT的AT指令

 AT+MQTTUSERCFG 设置MQTT用户配置

 AT+MQTTCONNCFG 设置MQTT的连接配置

AT+MQTTCONN 连接MQTT Broker

AT+MQTTPUB 发布MQTT消息

AT+MQTTPUBRAW 发布MQTT消息(二进制)

AT+MQTTSUB 订阅MQTT主题

AT+MQTTUNSUB 取消订阅MQTT主题

AT+MQTTCLEAN 关闭MQTT连接

AT+PING ping 包:返回响应时间(ms)

参考:

【1】ESP8266指令手册

【2】MQTT 协议 3.1.1  docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.pdf

【3】MQTT Version 5.0 https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.pdf

【4】 MQTT - The Standard for IoT Messaging

【5】GitHub - mcxiaoke/mqtt: MQTT协议3.1.1中文翻译版,IoT,物联网

【6】mqtt5.0-cn/01-Introduction.md at master · emqx/mqtt5.0-cn · GitHub

相关文章:

  • SAP EWM-拣货队列操作演示实例
  • 公众号查题功能接口系统使用教程
  • MySql5.7主从同步配置(gtid模式)
  • Linux文件系统管理
  • Python 程序的输出 | 第十一套(异常处理)
  • 每日算法刷题Day11-最大公约数、数组去重
  • 网络安全CTF竞赛模式、题目类别、所用工具小结
  • 80,90,00,房子最终砸在买房哪一代人手中?
  • 微服务项目:尚融宝(59)(核心业务流程:提现和还款(2))
  • jetson nano补充:根目录/usr刷机扩容 瘦身
  • Java工程师面试题
  • 网课查题接口使用
  • 算法练习(堆/栈/队列)
  • 大数据-ClickHouse技术一(安装部署)
  • 【Android入门】4、数据持久化:文件、SharedPreferences 和 Sqlite
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • [nginx文档翻译系列] 控制nginx
  • 2017年终总结、随想
  • 2017前端实习生面试总结
  • 30秒的PHP代码片段(1)数组 - Array
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • Druid 在有赞的实践
  • es6
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • JAVA多线程机制解析-volatilesynchronized
  • JSONP原理
  • Netty 4.1 源代码学习:线程模型
  • socket.io+express实现聊天室的思考(三)
  • Spring Cloud中负载均衡器概览
  • spring security oauth2 password授权模式
  • 动态规划入门(以爬楼梯为例)
  • 关于 Cirru Editor 存储格式
  • 机器学习学习笔记一
  • 使用SAX解析XML
  • 使用权重正则化较少模型过拟合
  • 树莓派 - 使用须知
  • 我是如何设计 Upload 上传组件的
  • 我这样减少了26.5M Java内存!
  • 新版博客前端前瞻
  • - 转 Ext2.0 form使用实例
  • 做一名精致的JavaScripter 01:JavaScript简介
  • ​如何在iOS手机上查看应用日志
  • ![CDATA[ ]] 是什么东东
  • #Linux(帮助手册)
  • #控制台大学课堂点名问题_课堂随机点名
  • (06)Hive——正则表达式
  • (3)STL算法之搜索
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (七)c52学习之旅-中断
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • (转)项目管理杂谈-我所期望的新人