bobenut / me

1 stars 0 forks source link

MQTT协议QoS质量等级 #5

Open bobenut opened 3 years ago

bobenut commented 3 years ago

使用PUBLISH报文在推送消息时,在报文的固定报头这一个字节的第1位和第2位设置值,用于控制QoS等级,也就是消息发送的质量等级,QoS等级有三种:

最多发送一次

QoS值为00(二进制),也就是无需签收。 客户端发送PUBLISH报文给服务端,服务端无需回复PUBACK报文,服务端再发送PUBLISH报文给订阅了当前主题的其他客户端发送PUBLISH报文后,其他客户端也无需回复PUBACK报文。

至少发送一次

QoS值为01(二进制),也就是需要一次签收。 客户端发送PUBLISH报文给服务端,服务端会回复PUBACK报文,表示服务端签收,服务端再发送PUBLISH报文给订阅了当前主题的其他客户端,发送PUBLISH报文后,按照协议要求其他客户端也要回复PUBACK报文,如果其他客户端没有回复PUBACK的,按照协议标准,服务端会重发PUBLISH报文,但是具体实现的服务端肯定不会无限制重发,会根据实际实现的性能要求和配置来决定重发次数,甚至于不重发,比如OneNet平台在没有收到其他客户端的签收报文时,默认就不会重发消息。

按照协议标准,服务端再没有收到其他客户端的签收报文时,可能会启动离线消息功能,服务端会将未签收的消息全部存下来,在下次客户端上线后,都会发给客户端,注意,此时如果不签收,还是会被存为离线消息。离线功能是否开启,依据于CONNECT报文的非固定报头中的Clean Session这一位,这一位如果设置的二进制码为0,就开启离线消息功能,设置1就代表关闭。

只发送一次

QoS值为02(二进制),需要二次确认签收。 客户端发送PUBLISH报文给服务端,服务端立即回复PUBREC报文进行签收,表示服务端收到发布的消息;然后,客户端回复PUBREL报文进行二次问询,服务端再回复PUBCOMP报文进行二次签收确认,表示发布消息整个过程完成。

服务端只有完成了PUBCOMP报文发送后,才能将消息再推送给其他的客户端;在PUBCOMP报文前,任何一步失败了,就不满足服务等级为2(十进制)的要求,那么服务端都不会把消息推送给其他客户端。

客户端与服务端推送消息,在满足整个质量等级的确认和签收过程后,服务端采用同样的质量等级和过程将消息推送给其他客户端,其他客户端要是没有正常回复两次签收的过程,服务端会要么将消息扔掉,要么依据Clean Session的设置将消息作为离线消息处理(按照标准协议的定义)

注意:大部分云平台都没有实现质量等级为2的过程,如果要实现,需要自行搭建。