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