SUBSCRIBE
3.8 SUBSCRIBE - 订阅主题 Subscribe to topics
Subscribe to topics
客户端向服务端发送SUBSCRIBE
报文用于创建一个或多个订阅。每次订阅都会记录客户端需要关联的一个或多个主题。为了将应用消息转发给匹配订阅的主题,服务端发送PUBLISH
报文给客户端。SUBSCRIBE
报文也(为每个订阅)指定了最大的QoS等级,服务端根据这个发送应用消息给客户端。
3.8.1 固定报头 Fixed header
Fixed header
图例3.20–SUBSCRIBE
报文固定报头
SUBSCRIBE
报文固定报头位 Bit76543210byte 1MQTT控制数据包类型(8) MQTT Control Packet Type (8)保留位 Reserved10000010byte 2剩余长度(2) Remaining Length
==SUBSCRIBE
控制报文固定报头的第3,2,1,0位是保留位,必须
分别设置为0,0,1,0。服务器必须
将任何其他值视为格式错误并关闭网络连接。== [MQTT-3.8.1-1]。
剩余长度字段
=可变报头的长度(2字节)+有效负载的长度。
3.8.2 可变报头 Variable header
Variable header
可变报头包含报文标识符。第2.3.1节提供了有关报文标识符的更多信息。
3.8.2.1 可变报头非规范示例 Variable header non normative example
Variable header non normative example
图例3.21 展示了报文标识符设置为10时的可变报头。
图例3.21-非规范示例的报文标识符等于10的可变报头
描述 Description76743210报文标识符 Packet Identifierbyte 1报文标识符的最高有效字节(0) Packet Identifier(0) MSB00000000byte 2报文标识符的最低有效字节(10) Packet Identifier LSB(10)00001010
3.8.3 有效负载 Payload
Payload
SUBSCRIBE
报文的有效负载包含了一个主题过滤器列表,它们表示客户端想要订阅的主题。==SUBSCRIBE
报文有效负载中的主题过滤器列表必须
是1.5.3节定义的UTF-8编码字符串== [MQTT-3.8.3-1]。服务端应该
支持包含在第4.7.1节中定义的通配符的主题过滤器。==如果服务端选择不支持包含通配符的主题过滤器,它就必须
拒绝任何包含通配符过滤器的订阅请求== [MQTT-3.8.3-2]。每一个过滤器后面跟着一个名为请求的服务质量等级的字节,它给出了服务端向客户端发送应用消息所允许的最大QoS等级。
==SUBSCRIBE
报文的有效负载必须
包含至少一对主题过滤器/QoS对。没有有效负载的SUBSCRIBE
报文是违反协议的== [MQTT-3.8.3-3]。有关错误处理的信息请查看4.8节。
请求的最大QoS字段被编码为一个字节,随后是一个或多个UTF-8编码的主题名。并且这些主题过滤器/QoS对会被连续地打包在一起。
图例3.22– SUBSCRIBE
报文有效负载格式
SUBSCRIBE
报文有效负载格式描述 Description76743210主题过滤器 Topic Filterbyte 1长度的最高有效字节 Length MSBbyte 2长度的最高有效字节 Length MSBbyte 3..N主题过滤器 Topic Filter请求的服务质量等级 Requested QoS保留位Reserved服务质量等级QoSbyte N+1000000XX
当前版本的协议没有使用请求QoS字节的高六位,它们留作将来使用。==如果有效负载中的任何位是非零值,或者QoS不是0,1或2,服务端必须
认为SUBSCRIBE
报文是格式错误的并关闭网络连接== [MQTT-3-8.3-4]。
3.8.3.1 有效负载的非规范示例 Payload non normative example
Payload non normative example
图例3.23–有效负载字节格式的非规范示例 展示了 表3.5–有效负载非规范示例 中简略描述的
SUBSCRIBE
报文的有效负载。
表3.5-有效负载的非规范示例
主题名Topic Name“a/b” 请求的服务质量等级Requested QoS0x01 主题名Topic Name“c/d” 请求的服务质量等级Requested QoS0x02
图例3.23-有效负载字节格式的非规范示例
描述 Description76743210主题过滤器 Topic Filterbyte 1长度最高有效字节(0) Length MSB (0)00000000byte 2长度的最低有效字节(3) Length LSB (3)00000011byte 3‘a’ (0x61)01100001byte 4‘/’ (0x2F)00101111byte 5‘b’ (0x62)01100010请求的服务质量等级 Requested QoSbyte 6请求的服务质量等级(1) Requested QoS(1)00000001\主题过滤器 Topic Filterbyte 7长度最高有效字节(0) Length MSB (0)00000000byte 8长度的最低有效字节(3) Length LSB (3)00000011byte 9‘c’ (0x63)01100011byte 10‘/’ (0x2F)00101111byte 11‘d’ (0x64)01100100请求的服务质量等级 Requested QoSbyte 12请求的服务质量等级(2) Requested QoS(2)00000010
3.8.4 响应 Response
Response
==服务端收到客户端发送的一个SUBSCRIBE
报文时必须
使用SUBACK
报文响应== [MQTT-3.8.4-1]。==SUBACK
报文必须
和正在确认的SUBSCRIBE
报文有相同的报文标识符== [MQTT-3.8.4-2]。
允许服务端在发送SUBACK
报文之前就开始发送匹配订阅的PUBLISH
报文。
==如果服务端收到包含与现有订阅的主题过滤器相同的主题过滤器的SUBSCRIBE
报文,那么它就必须
使用新的订阅完全替代现有的订阅。新订阅的主题过滤器和之前订阅的相同,但是它的最大QoS值可以不同。与这个主题过滤器匹配的任何现存的保留消息必须
重发,但是发布流程不能
中断== [MQTT-3.8.4-3]。
如果主题过滤器不同于任何现存订阅的过滤器,服务端会创建一个新的订阅并发送所有匹配的保留消息。
==如果服务端收到包含多个主题过滤器的SUBSCRIBE
报文,它必须
像收到了一系列的多个SUBSCRIBE
报文一样处理那个,除非服务端需要将这些主题过滤器的响应组合成一个SUBACK
响应== [MQTT-3.8.4-4]。
==服务端发送给客户端的SUBACK
报文必须包含对每一组主题过滤器/QoS对的返回码。该返回码必须
显示为该订阅获得的最大QoS授权,或者表明订阅失败== [MQTT-3.8.4-5]。==服务端可以授予比订阅者要求的低一些的QoS等级。为响应订阅而发出的消息的有效负载的QoS必须
是原始发布消息的QoS和服务端授予的QoS两者中的最小值。如果原始消息的QoS是1而被授予的最大QoS是0,允许服务端重复发送一个消息的副本给订阅者== [MQTT-3.8.4-6]。
非规范性注解 对某个特定的主题过滤器,如果正在订阅的客户端被授予的最大QoS等级是1,那么匹配这个过滤器的QoS 0等级的应用消息会按QoS 0等级分发给这个客户端。这意味着客户端最多收到这个消息的一个副本。从另一方面说,发布给同一主题的QoS等级2的消息会被服务端降级到QoS等级1再分发给客户端,因此客户端可能会收到重复的消息副本。 如果正在订阅的客户端被授予的最大QoS等级是0,那么原来按QoS 2等级发布给客户端的应用消息在传输时可能会丢失,但是服务端不应该发送重复的消息副本。发布给同一主题的QoS 1等级的消息在传输给客户端时可能也会丢失或重复。 非规范性注解 使用QoS等级2订阅一个主题过滤器等于是说:我希望按照它们发布时的QoS等级接收与这个过滤器匹配的消息 。这意味着,发布者负责确定消息可以传递的最大QoS等级,而订阅者可以要求服务端降低QoS到更适合它的等级。
Last updated