MQTT v5.0------SUBSCRIBE 报文
Posted saryli
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MQTT v5.0------SUBSCRIBE 报文相关的知识,希望对你有一定的参考价值。
SUBSCRIBE 报文
固定报头:
剩余长度字段
表示可变报头的长度加上有效载荷的长度,被编码为变长字节整数。
可变报头
SUBSCRIBE报文可变报头按顺序包含以下字段:报文标识符(Packet Identifier),属性(Properties)。
范例:可变报头(没有属性),报文标识符为10
SUBSCRIBE 报文的属性存在可变头部中。
- 11 (0x0B),订阅标识符(Subscription Identifier)标识符。取值范围从1到268,435,455。。订阅标识符的值为0或包含多个订阅标识符将造成协议错误。
- 38 (0x26),用户属性(User Property)标识符。
.SUBSCRIBE载荷
MQTT 5.0 中 SUBSCRIBE 报文中的 Payload 包含了订阅选项(Subscription Options)。
SUBSCRIBE报文的载荷包含一列主题过滤器,指明客户端希望订阅的主题。主题过滤器必须为UTF-8 编 码的字符串。每个主题过滤器之后跟着一个订阅选项(Subscription Options)字节。
订阅选项(Subscription Options)的第 0 位和第 1 位表示 QoS 最大值。该字段给出了服务器可以发送给客户端应用消息的最大 QoS 等级。如果 QoS 值为 3,就会触发协议错误。
订阅选项第 2 位表示非本地选项(No Local)。如果值为 1,应用消息就不会发布给订阅发布主题的发布者本身,如果在共享订阅中将该选项设置为 1 的话,就会触发协议错误。
订阅选项的第 3 位表示保留为已发布(Retain As Published)。若该值为 1,服务器须将转发消息的 RETAIN flag 设为与接收到的 PUBLISH 报文的 RETAIN flag 一致。若该值为 0,不管接收到的 PUBLISH 报文中的 RETAIN flag 是何值,服务器都需将转发消息的 RETAIN flag 置为 0。
订阅选项的第 4 第 5 位表示保留处理 (Retain Handling)。此选项指示当订阅建立时,是否发送保留消息。此选项不影响之后的任何保留消息的发送。如果没有匹配主题过滤器的保留消息,则此选项所有 值的行为都一样。值可以设置为:
- 0 = 订阅建立时发送保留消息
- 1 = 订阅建立时,若该订阅当前不存在则发送保留消息
- 2 = 订阅建立时不要发送保留消息
订阅选项的第 6 第 7 位是预留给未来使用的。如果有效载荷的任何一个预留位非零,那么服务器就会将该报文视为格式错误的报文。
已存在订阅的情况下不发送保留消息是很有用的,比如重连完成时客户端不确定订阅是否在之前的 会话连接中被创建。
不发送保存的保留消息给新创建的订阅是很有用的,比如客户端希望接收变更通知且不需要知道最 初的状态。
对于某个指示其不支持保留消息的服务端,发布保留和保留处理选项的所有有效值都将得到同样的 结果:订阅时不发送任何保留消息,且所有消息的保留标志都会被设置为0。
范例:
SUBSCRIBE行为
当服务端收到来自客户端的SUBSCRIBE报文时,必须使用SUBACK报文作为相应
SUBACK报文必须和待确认的SUBSCRIBE报文有相同的报文标识符
允许服务端在发送SUBACK报文之前就开始发送与订阅相匹配的PUBLISH报文
如果服务端收到的SUBSCRIBE报文中的一个主题过滤器与当前会话的一个非共享订阅(Non-shared Subscription)相同,那么必须使用新的订阅替换现存的订阅 。新订阅的主题过滤器与之前 的订阅相同,但其订阅选项可能不同。如果保留处理选项为0,任何匹配该主题过滤器的保留消息必须被重发,但替换订阅不能造成应用消息的丢失 。
如果服务端收到的非共享主题过滤器(Non-shared Topic Filter)不同于当前会话的任何主题过滤器,一个新的非共享订阅将被创建。如果保留处理选项不为2,所有相匹配的保留消息将发送给客户端。
如果服务端收到的主题过滤器与服务端已存在的某个共享订阅(Shared Subscription)主题过滤器相同,则将此会话添加到该共享订阅中。不发送任何保留消息。
如果服务端收到的共享订阅主题过滤器(Shared Subscription Topic Filter)与任何已存在的共享订阅主题 过滤器都不同,一个新的共享订阅将被创建。将此会话作为订阅者添加到该共享订阅。不发送任何保留消息。
如果服务端收到的SUBSCRIBE报文包含多个主题过滤器,服务端必须当做收到一系列多个SUBSCRIBE 报文来处理--除了将它们的响应组合为单个SUBACK响应
服务端发送给客户端的SUBACK报文必须为每一个主题过滤器/订阅选项对包含一个原因码,此原因码必须说明为该订阅授予的最大QoS等级,或指示订阅失败
。服务端可能授予了低于订阅者所请求的最大QoS等级。响应该订阅的应用消息QoS等级必须为该消息发布时的QoS等级和服务端授予的最大QoS等级二者最小值
在原始消息发布的QoS等级为1,且授予的 最大QoS等级为0的情况下,服务端允许发送重复的消息副本给订阅者。
如果订阅客户端的某个主题过滤器已被授予的最大QoS等级为1,那么匹配此过滤器的QoS等级为0的应用消息按照QoS等级为0分发给此客户端。这意味着客户端最多只能收到该消息的一个 副本。
另一方面,发布到相同主题的QoS等级为2的消息,其QoS等级被服务端降级为1以便分 发给该客户端。因此该客户端可能收到此消息的多个副本。
如果订阅客户端被授予的最大QoS等级为0,那么按照QoS等级为2发布的应用消息在繁忙时可 能会丢失,但服务端不应该发送重复的消息副本。发布到相同主题的QoS等级为1的消息,分发 给该客户端时可能会丢失或重复。
以上是关于MQTT v5.0------SUBSCRIBE 报文的主要内容,如果未能解决你的问题,请参考以下文章