MQTT Qos杂谈(二)

基于标准MQTT协议3.1版本,MQTT Qos与报文标识字段,清理会话标志,遗嘱标志等关联密切,下面是个人的一些总结,错误之处欢迎指正,谢谢!

报文标识符字段

在很多控制报文的可变头部包含一个两字节的报文标识符字段。这些报文是PUBLISH(Qos > 0),PUBACK,PUBREC,PUBCOMP,SUBSCRIBE,SUBACK,UNSUBSCIBE,UNSUNACK。

SUBSCRIBE,UNSUBSCRIBE和PUBLISH(Qos > 0)控制报文必须包含一个非零的16位比特报文标识符(Packet Identifier)。客户每次发送一个新的这类型的报文时,都必须分配一个当前未使用的报文标识符。如果一个客户端要重发这个特殊的控制报文,在随后重发那个控制报文时,也必须使用相同的报文标识符。当客户端处理完这个报文对应的确认后,这个报文标识符就可以释放重用。

  • Qos 1 的PUBLISH对应的是PUBACK;
  • Qos 2的PUBLISH对应的是PUBCOMP;
  • 与SUBSCRIBE或者UNSUBSCRIBE对应的分别是SUBACK,或UNSUBACK。
  • 发送一个Qos 0的PUBLISH报文时,相同的条件也适用于服务端。

清理会话标志(Clean Session)

如果清理会话(Clean Session)标志位被设置为0,服务器必须基于当前会话(使用客户端标识识别符)的状态恢复与客户端的通信。如果没有与这个客户端标识符关联的会话,服务器必须创建一个新的会话。当连接断开后,客户端和服务器端必须保存会话信息。当前清理会标志为0的会话连接断开之后,服务器端必须将之后的Qos 1和Qos 2级别的消息保存为会话状态的一部分,如果这些消息匹配断开连接时客户端的任何订阅,如无端也可以保存满足相同条件的Qos 0级别的消息。

客户端的会话状态包括:

  • 已经发送给服务端, 但是还没有完成确认的QoS 1和QoS 2级别的消息
  • 已从服务端接收, 但是还没有完成确认的QoS 2级别的消息。

服务端的会话状态包括:

  • 会话是否存在, 即使会话状态的其它部分都是空。
  • 客户端的订阅信息。
  • 已经发送给客户端, 但是还没有完成确认的QoS 1和QoS 2级别的消息。
  • 即将传输给客户端的QoS 1和QoS 2级别的消息。
  • 已从客户端接收, 但是还没有完成确认的QoS 2级别的消息。
  • 可选, 准备发送给客户端的QoS 0级别的消息。

保留消息不是服务端会话状态的一部分, 会话终止时不能删除保留消息。当清理会话标志设置为1时,客户端和服务端的状态删除不需要是原子操作。

非规范评注

为了确保发生故障时状态的一致性,客户端应该使用会话状态标志为1的重复请求连接,直到连接成功。

非规范评注

一般来说,客户端连接时,总是将清理会话标志位设置为0,或1。并且不会交替使用两种值。这个选择取决于具体的应用场景。

清除会话标志设置为1的客户端,不会收到旧的应用消息,而且每次连接成功后,都需要重新订阅相关需要的主题。

清理会话标志设置为0的客户端,会收到在它连接断开期间,服务器端发布的Qos 1和Qos 2级别的消息。因此要确保不丢失断开连接期间的消息,需要使用Qos 1 或 Qos 2级别,同时将清理会话标志设置为0。

非规范评注

清理会话标志为0的客户端连接时,它请求服务端在连接断开后,保留它的MQTT会话状态。如果打算在之后的某一个时间点重连这个服务端,客户端连接应该只使用清理会话标志为0的。当客户端决定不再使用这个会话时,应该将清理会话标志设置为1,最后在连接一次,然后在断开连接。

 

Qos服务等级

Qos = 0必须准守的规范

  • 对于Qos 0的消息,发布者发布消息时,DUP标志位必须设置为0;
  • Qos等于0的PUBLISH报文,不能包含报文标识符;
  • 对于Qos 0的消息,DUP标志位必须设置为0;
  • 如果客户端或者服务器端,请求重发一个PUBLISH报文时,必须设置DUP标志为1,对于Qos 0的消息,DUP的标志必须设置为0;
  • 如果遗嘱标志设置为0,遗嘱Qos也必须设置为0;
  • 如果遗嘱标志设置为0,连接标志中的Will Qos 和 Will retain字段必须设置为0,并且有效载荷中不能包含Will Topic和Will message字段;
  • 如果服务端收到一条保留(RETAIN)标志位为1的Qos 0的消息,服务端必须丢弃之前为那个主题保留的任何消息。服务端应该讲这个新的Qos 0的消息当作那个主题的新保留消息,但是任何时候都可以选择丢弃它——如果这种情况发生了,那个主题将没有保留消息。

Qos = 1需要准守的规范

发送者

  • 每一次发送新的应用消息,都必须分配一个未使用的报文标识符;
  • 发送的PUBLISH报文必须包含报文标识符,且Qos为1,DUP为0;
  • 必须将这个PUBLISH报文看作是未确认的,直到从接收者那里收到对应的PUBACK报文;注意一点:一旦发送者收到PUBACK报文,这个报文的报文标识符就可以重用了;
  • 允许发送者在等在确认时,使用不同的报文标识符发送后续的PUBLISH报文。

接收者

  • 响应的PUBACK报文必须包含一个报文表示符,这个表示符来自收到的,已经接受所有权的PUBLISH报文;
  • 接收者发送了PUBACK报文之后,接收者必须将任何包含相同报文标识符的入站PUBLISH报文,当做一个新的消息,并且忽略它的DUP标志位的值;

遗嘱消息

  • 如果遗嘱标志设置为1,遗嘱的Qos可以等于0,1,2。但是不能为其他值。(原官方文档说,是不能为3)

 

异常情况

如果服务端实现不授权某个客户端发布PUBLISH报文,它没有办法通知那个客户端。它按照正常的Qos 规则发送一个正面的确认,或者关闭网络连接。

SUBSCRIBE报文的有效载荷必须包含至少一对主题过滤器 和 QoS等级字段组合。没有有效载荷的SUBSCRIBE报文是违反协议的。

如果有效载荷中的任何位是非零值,或者QoS不等于0,1或2,服务端必须认为SUBSCRIBE报文是不合法的并关闭网络连接。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值