3.8订阅 - 订阅主题
SUBSCRIBE数据包从客户端发送到服务器以创建一个或多个订阅。每个订阅都注册客户对一个或多个主题的兴趣。服务器将PUBLISH数据包发送到客户端,以便将发布的应用程序消息转发到与这些订阅匹配的主题。SUBSCRIBE数据包还指定(对于每个订阅)服务器可以将应用程序消息发送到客户端的最大QoS。
3.8.1 Fixed Header 固定标题
位 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
字节1 |
MQTT控制包类型(8) |
保留的 |
||||||
|
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
字节2 |
剩余长度 |
SUBSCRIBE控制分组的固定报头的比特3,2,1和0被保留,并且必须分别设置为0,0,1和0。服务器必须将任何其他值视为格式错误并关闭网络连接 [MQTT-3.8.1-1] 。
剩余长度字段
这是变量头的长度(2个字节)加上有效载荷的长度。
3.8.2 varliable header 变量头
变量头包含数据包标识符。第2.3.1节提供了有关数据包标识符的更多信息。
图3.21显示了包标识符设置为10的变量头。
|
描述 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
包标识符 |
|||||||||
字节1 |
包标识符MSB(0) |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
字节2 |
包标识符LSB(10) |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
3.8.3 Payload 效载荷
SUBSCRIBE数据包的有效负载包含主题过滤器列表,指示客户端要订阅的主题。SUBSCRIBE数据包有效负载中的主题过滤器必须是第1.5.3 节[MQTT-3.8.3-1]中定义的UTF-8编码字符串。服务器应该支持包含第4.7.1节中定义的通配符的主题过滤器。如果它选择不支持包含通配符的主题过滤器,它必须拒绝其过滤器包含它们的任何订阅请求 [MQTT-3.8.3-2]。每个过滤器后跟一个称为请求QoS的字节。这提供了服务器可以向客户端发送应用程序消息的最大QoS级别。
SUBSCRIBE包的有效载荷必须包含至少一个主题过滤器/ QoS对。没有有效载荷的SUBSCRIBE数据包是协议违规 [MQTT-3.8.3-3]。有关处理错误的信息,请参见第4.8节。
请求的最大QoS字段在每个UTF-8编码的主题名称后面的字节中编码,并且这些主题过滤器/ QoS对被连续打包。
描述 |
7 |
6 |
五 |
4 |
3 |
2 |
1 |
0 |
主题过滤器 |
||||||||
字节1 |
长度MSB |
|||||||
字节2 |
长度LSB |
|||||||
字节3..N |
主题过滤器 |
|||||||
请求的QoS |
||||||||
|
保留的 |
服务质量 |
||||||
字节N + 1 |
0 |
0 |
0 |
0 |
0 |
0 |
X |
X |
请求的QoS字节的高6位不在当前版本的协议中使用。它们留作将来使用。如果有效载荷中的任何保留位非零,或者QoS不是0,1或2 [MQTT-3-8.3-4] ,则服务器必须将SUBSCRIBE数据包视为格式错误并关闭网络连接。
图3.23 - 有效载荷字节格式非规范性示例显示了表3.5中简要描述的SUBSCRIBE数据包的有效载荷- 有效载荷非规范示例。
主题名称 |
“A / B” |
请求的QoS |
0×01 |
主题名称 |
“光盘” |
请求的QoS |
0×02 |
|
描述 |
7 |
6 |
五 |
4 |
3 |
2 |
1 |
0 |
主题过滤器 |
|||||||||
字节1 |
长度MSB(0) |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
字节2 |
长度LSB(3) |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
字节3 |
'a'(0x61) |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
字节4 |
'/'(0x2F) |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
字节5 |
'b'(0x62) |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
0 |
请求的QoS |
|||||||||
字节6 |
请求的QoS(1) |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
主题过滤器 |
|||||||||
字节7 |
长度MSB(0) |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
字节8 |
长度LSB(3) |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
字节9 |
'c'(0x63) |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
字节10 |
'/'(0x2F) |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
字节11 |
'd'(0x64) |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
请求的QoS |
|||||||||
字节12 |
请求的QoS(2) |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
3.8.4 Response 回应
当服务器从客户端收到SUBSCRIBE数据包时,服务器必须以SUBACK数据包 [MQTT-3.8.4-1]进行响应。SUBACK分组必须具有与其确认的SUBSCRIBE分组相同的分组标识符 [MQTT-3.8.4-2]。
在服务器发送SUBACK数据包之前,允许服务器开始发送与订阅匹配的PUBLISH数据包。
如果服务器收到包含与现有Subscription主题过滤器相同的主题过滤器的SUBSCRIBE数据包,那么它必须用新的订阅完全替换现有的Subscription。新订阅中的主题过滤器将与之前的订阅中的主题过滤器相同,但其最大QoS值可能不同。必须重新发送与主题过滤器匹配的任何现有保留消息,但不得中断出版物流 [ MQTT-3.8.4-3]。
如果主题过滤器与任何现有的Subscription过滤器不同,则会创建新的Subscription并发送所有匹配的保留消息。
如果服务器收到包含多个主题过滤器的SUBSCRIBE数据包,则它必须处理该数据包,就好像它已经收到多个SUBSCRIBE数据包的序列一样,除了它将它们的响应组合成单个SUBACK响应 [MQTT-3.8.4-4]。
服务器发送给客户端的SUBACK数据包必须包含每个主题过滤器/ QoS对的返回码。此返回代码必须显示为该订阅授予的最大QoS或指示订阅失败[ MQTT- 3.8.4-5] 。服务器可能授予比请求的订户更低的最大QoS。响应订阅而发送的有效载荷消息的QoS必须是最初发布的消息的QoS的最小值和服务器授予的最大QoS。在原始消息以QoS 1发布并且授予的最大QoS为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降级为更适合其使用的QoS。