MQTT(Message Queuing Telemetry Transport),即消息队列遥测传输协议,是一种基于发布/订阅的消息传输协议。其轻量、开放、简洁和易实现的特点能够适用于要求代码量小、网络带宽资源匮乏的情景,如机器间通信(M2M)、物联网等。
Property字段(5.0新增)
携带一组属性和属性长度:
属性长度被编码为变长字节整数,不包含用于编码属性长度自带的字节数
属性包含一段数据和定义了属性用途和数据类型的标识符
正是这个字段,使得 MQTT 5.0 可以支持众多的新特性。而在MQTT 3.1.1中,MQTT没有任何可以拓展的地方,限制了MQTT拓展功能的可能性。
例如CONNECT报文新增
User Property
这个属性在property里面,它可以添加两端约定的数据。例如可以加入类似HTTP的“Header:value”信息。MQTT本身没有类似HTTP的HOST信息,我们可以使用User Property特性让MQTT支持。
Message-expiry-interval
该字段可以在publish报文的属性字段添加,消息过期间隔是一个四字节的整数,表示应用消息的生命周期,单位是秒.
如果 PUBLISH 报文不设置消息过期间隔,那么应用消息不会过期。
如果 PUBLISH 报文设置了消息过期间隔,并且消息过期将已经过期,服务端还没开始向匹配的订阅者交付该消息,那么服务端必须删除该消息。
clean session与clean start
在之前的MQTT版本,当cleansession为0时,server和client会尝试保存session信息(sub信息、PUBLISH状态等),但是有个问题,server 不知道需要保存这个session多久。MQTT 5.0 就 在 Property字段中增加了Session Expiry Interval属性来告知server这个session希望被保存多久。
如果MQTT 5.0 不携带 Session Expiry Interval或者 Session Expiry Interval设置为0,server和client则不会保存session信息。
如果Session Expiry Interval设置为0xffffffff,则表示session永远不会老化。
当然,这个字段是需要配合Clean Start使用的,如果Clean Start为1,那么 Session Expiry Interval设置多大都无意义。
Reason code
MQTT 3.1.1 只有CONNACK有是否成功还是失败的标志位,现在MQTT 5.0所有的ACK都有该标志位。在ACK中回复一个原因码
Topic Alias
它允许用户将主题长度较长且常用的主题名缩减为一个双字节整数来降低发布消息时的带宽消耗。主题别名字段他是一个双子节整数,作为属性字段,编码在PUBLISH报文的可变报文部分。并且受到CONNECT报文和CONNACK报文中的**topic-alias-maximum**限制。
在之前的MQTTv3协议中,如果客户端在某次连接中发送大量相同主题的消息,在每一条PUBLISH中发送主题名,造成资源的浪费。而现在使用主题别名只需要发送最多两个字节。同时计算机处理整数的效率高于处理字符串的效率,对于客户端或服务端在报文解析时消耗的计算资源也有了一定的节约。
Receive Maximum
通知对方未处理的最大的 Qos1 或者 Qos2 PUBLISH消息个数,如果不存在,则默认是65535。
因为当处理 Qos > 0 的PUBLISH的时候,需要回复对端PUBACK、PUBREC PUBCOMP等。Receive Maximum属性提供了告诉对端发送Qos>0的PUBLISH的最大数量,对端发现未决PUBLISH个数等于Receive Maximum时,不能再发送Qos > 0 的PUBLISH消息了
作用:流量控制。
Payload Format Indicator
指定了PUBLISH 消息的message部分是utf8格式的还是二进制的,接收方必须验证payload是否是该属性定义的格式。
Payload Format Indicator 为 0,表示是二进制,和不携带该属性的语义是一样的。
Payload Format Indicator 为 1,表示 是utf8编码数据。
共享订阅
在订阅一个主题的消息的时候,我们可以通过建立一个共享订阅组,发布者pub消息,给每一个客户端,不需要每个人都接收到,而是所有的客户端共享这些消息
共享订阅也有一个主题过滤器,唯一的区别是在于共享订阅的主题过滤器格式必须是$share/{ShareName}/{filter}格式。
$share 前缀表示这个是一个共享订阅
ShareName是一个字符串,订阅会话通过使用相同的 ShareName表示使用同一个订阅,匹配该订阅的消息每次只发布给其中一个session
request/response 模式
MQTT5.0为了支持request/response 模式在publish报文提供ResponseTopic字段以及Correlation Data属性。
客户端A pub主题为testA的消息,clientB订阅并收到,如果pub的属性字段有response topic:testrsp那么clientB会pub主题为testrsp的消息字段,订阅该主题的客户端将会收到。
客户端ID
将被 Broker 用于唯一标识客户端以及客户端的当前状态,例如客户端的订阅列表,报文收发状态等。客户端断开重连时,Broker 将根据 Client ID 来完成会话的恢复。
Will Properties(遗嘱属性)
- Will Delay Interval:遗嘱消息延时间隔,用于推迟Will Message(遗嘱消息)的发布。
- Payload Format Indicator:消息体格式指示,1表示Will Message的编码为UTF-8,0则无效字符。
- Message Expiry Interval:消息到期间隔。
- Content Type:内容类型,此处用来表明Will Message的内容。
- Response Topic:回复主题,用作回复消息的主题名。
- Correlation Data: 相关数据。
- User Property:用户属性,由用户自己定义。
订阅选项:
No Local
在 MQTT v3.1.1 中,如果你订阅了自己发布消息的主题,那么你将收到自己发布的所有消息。
而在 MQTT v5 中,如果你在订阅时将此选项设置为 1,那么服务端将不会向你转发你自己发布的消息。
Retain As Publish
这一选项用来指定服务端向客户端转发消息时是否要保留其中的 RETAIN 标识,注意这一选项不会影响保留消息中的 RETAIN 标识。因此当 Retain As Publish 选项被设置为 0 时,客户端直接依靠消息中的 RETAIN 标识来区分这是一个正常的转发消息还是一个保留消息,而不是去判断消息是否是自己订阅后收到的第一个消息(转发消息甚至可能会先于保留消息被发送,视不同 Broker 的具体实现而定)。
Retain Handling
这一选项用来指定订阅建立时服务端是否向客户端发送保留消息:
Retain Handling 等于 0,只要客户端订阅成功,服务端就发送保留消息。
Retain Handling 等于 1,客户端订阅成功且该订阅此前不存在,服务端才发送保留消息。毕竟有些时候客户端重新发起订阅可能只是为了改变一下 QoS,并不意味着它想再次接收保留消息。
Retain Handling 等于 2,即便客户订阅成功,服务端也不会发送保留消息。
增强验证
AUTH报文被从客户端发送给服务端,或从服务端发送给客户端,作为扩展认证交换的一部分,比如质询/ 响应认证。如果CONNECT报文不包含相同的认证方法,则客户端或服务端发送AUTH报文将造成协议错误(Protocol Error)。
增强认证可以实现对客户端和服务器的双向认证,服务器可以验证连接的客户端是否是真正的客户端,客户端也可以验证连接的服务器是否是真正的服务器,从而提供了更高的安全性。
在增强认证的过程中,客户端与服务器需要进行多次认证数据的交换,**每次交换都需要通过认证算法对认证数据进行加解密的计算(双方验证加密的数据),**所以它需要更多的计算资源以及更稳定的网络环境,因此它并不适合算力薄弱、网络波动大的边缘设备,而支持增强认证的 MQTT服务器也需要准备更多的计算资源来应对大量的连接。
SCRAM 认证非规范示例
客户端到服务端: CONNECT 认证方法="SCRAM-SHA-1",认证数据=client-first-data
服务端到客户端: AUTH 原因码=0x18,认证方法="SCRAM-SHA-1",认证数据=server-first-data
客户端到服务端: AUTH 原因码=0x18,认证方法="SCRAM-SHA-1",认证数据=client-final-data
服务端到客户端: CONNACK 原因码=0,认证方法="SCRAM-SHA-1",认证数据=server-final-data
版权归原作者 Exy- 所有, 如有侵权,请联系我们删除。