概述
3.8订阅 - 订阅主题
SUBSCRIBE数据包从客户端发送到服务器以创建一个或多个订阅。每个订阅都注册客户对一个或多个主题的兴趣。服务器将PUBLISH数据包发送到客户端,以便将发布的应用程序消息转发到与这些订阅匹配的主题。SUBSCRIBE数据包还指定(对于每个订阅)服务器可以将应用程序消息发送到客户端的最大QoS。
3.8.1 Fixed Header 固定标题
图3.20 - SUBSCRIBE数据包固定标头
位 | 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.8.2.1 变量头非规范性示例
图3.21显示了包标识符设置为10的变量头。
图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对被连续打包。
图3.22 - SUBSCRIBE数据包有效载荷格式
描述 | 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.8.3.1 有效载荷非规范性示例
图3.23 - 有效载荷字节格式非规范性示例显示了表3.5中简要描述的SUBSCRIBE数据包的有效载荷- 有效载荷非规范示例。
表3.5 - 有效载荷非规范性示例
主题名称 | “A / B” |
请求的QoS | 0×01 |
主题名称 | “光盘” |
请求的QoS | 0×02 |
图3.23 - 有效载荷字节格式非规范性示例
| 描述 | 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。
最后
以上就是怕孤单柠檬为你收集整理的IOT-MQTT协议-控制数据包-SUBSCRIBE的全部内容,希望文章能够帮你解决IOT-MQTT协议-控制数据包-SUBSCRIBE所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复