前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MQTT Packet详解【03】:SUBSCRIBE & UNSUBSCRIBE

MQTT Packet详解【03】:SUBSCRIBE & UNSUBSCRIBE

作者头像
Hello工控
发布于 2025-05-10 02:49:11
发布于 2025-05-10 02:49:11
10400
代码可运行
举报
文章被收录于专栏:Hello工控Hello工控
运行总次数:0
代码可运行

在上两期文章中,我们介绍了MQTT 5.0中的:

MQTT Packet详解【01】:CONNECT & CONNACK

MQTT Packet详解【02】:PUBLISH & PUBACK

我这期重点介绍SUBCRIBE和UNSUBSCRIBE订阅和取消订阅数据包结构。

在MQTT中,SUBSCRIBE包用于发起订阅请求,而SUBACK包用于返回订阅结果。取消订阅时使用UNSUBSCRIBE和UNSUBACK数据包。订阅主题比取消订阅更常用。但是,在本文中,我们仍然将介绍订阅和取消订阅数据包的结构和组成。

代码语言:javascript
代码运行次数:0
运行
复制
图片
图片

Sample样例

首先,我们使用Wireshark捕获一个真实的MQTT订阅请求和响应。在这里,我们使用MQTTX CLI向公共MQTT服务器发起订阅请求。以下命令将创建一个订阅,主题demo,最大QoS设置为2:

以下是Wireshark捕获的SUBSCRIBE和SUBACK数据包:

此十六进制字节串对应于以下数据包内容:

也许你开始想知道他们是如何完成从简单的MQTTX CLI命令到复杂的数据包数据的转换的,或者好奇如何在捕获MQTT数据包时提取所需的信息。

在下面介绍SUBSCRIBE、SUBACK、UNSUBSCRIBE和UNSUBACK的数据包结构时,您的问题将得到解答。

图片
图片

SUBSCRIBE Packet Structure

SUBSCRIBE包结构

Fixed Header固定头

在SUBSCRIBE数据包中,固定报头中第一个字节的高4位必须设置为8(0b1000),而保留的低4位必须设置为2(0b0010)。在第一个字节之后,仍然有剩余长度字段,它是一个可变字节整数。

Variable Header 变量头

SUBSCRIBE数据包的变量报头按顺序包含以下字段:

  • Packet Identifier数据包标识符:一个两字节的标识符,用于唯一标识订阅请求。PUBLISH、SUBSCRIBE和UNSUBSCRIBE数据包使用一组数据包标识符,这意味着它们不能同时使用相同的数据包标识符。
  • Properties属性:下表列出了SUBSCRIBE数据包的所有可用属性。

Payload 载荷

SUBSCRIBE数据包的有效载荷包含一个或多个主题过滤器和订阅选项对。Topic Filter是一个UTF-8 Encoded String,用于向服务器指示客户端希望订阅的主题,而Subscription Option仅占用一个字节,目前由以下四个选项组成:

  • 保留(Bit7,6) 保留位,当前必须设置为0。
  • Retain Handling(Bit 5,4) 用于指示当订阅建立时,服务器是否需要向该订阅发送保留的消息。
  • Retain As Published(Bit 3)用于指示服务器在将应用消息转发给该订阅时,是否需要在消息中保留Retain标志。
  • No Local(Bit 2)用于指示服务器是否可以将应用程序消息转发给消息的发布者。在桥接方案中通常使用No Local和Retain As Published。
  • Maximum QoS (Bit 1, 0)此选项确定服务器在将消息转发到此订阅时可以使用的最大QoS级别。如果消息的原始QoS超过此限制,服务器将降级QoS以确保消息传递。
图片
图片

SUBACK Packet Structure SUBACK 数据包结构

Fixed Header固定头

对于SUBACK包,固定报头的第一个字节由MQTT控制包类型的高4位和保留位的低4位组成,前者必须为9(0b1001),后者必须为0(0b0000).

Variable Header 变量头

SUBACK数据包的变量报头按顺序包含以下字段:

  • Packet Identifier数据包标识符:SUBACK数据包中的数据包标识符必须与相应的SUBSCRIBE数据包一致,以便对方能够正确匹配响应和请求。
  • Properties属性:下表列出了SUBACK数据包的所有可用属性。

Payload 载荷

SUBACK 包的负载包含一个原因代码列表,原因代码表示订阅是否成功或失败的原因。一个原因代码对应于 SUBSCRIBE 包中的一个主题过滤器,因此 SUBACK 包中原因代码的顺序必须与 SUBSCRIBE 包中主题过滤器的顺序一致。

下表列出了 SUBACK 报文的所有原因代码:

UNSUBSCRIBE Packet Structure UNSUBSCRIBE 数据包结构

Fixed Header固定头

与 SUBSCRIBE 包相同,唯一的区别是 Packet Type 字段的值从 8(0b1000)变为 10(0b1010)

紧随其后的是剩余长度字段,它指示当前数据包中剩余的字节数。

Variable Header 变量头

与 SUBSCRIBE 包相同。

Payload 载荷

UNSUBSCRIBE 报文的负载包含一个或多个客户端希望退订的主题过滤器。这些主题过滤器也是 UTF-8 编码的字符串,多个主题过滤器紧密相连。

UNSUBACK Packet Structure UNSUBACK 数据包结构

Fixed Header固定头

对于 UNSUBACK 报文,固定头部的第一个字节由 MQTT 控制报文类型的高位 4 位和保留位的低位 4 位组成,前者必须是 11(0b1011),后者必须是 0(0b0000)。

Variable Header 变量头

UNSUBACK 的可变头部包含按顺序排列的包标识符和属性字段,可用属性与 SUBACK 包中的属性相同。

Payload 载荷

UNSUBACK 的负载还包含一个 Reason Code 列表。Reason Code 表示取消订阅是否成功或失败。这些 Reason Code 与 UNSUBSCRIBE 包中的 Topic Filters 按顺序对应。

以下表格列出了 UNSUBACK 包的所有可用 Reason Codes:

结论

SUBSCRIBE 和 SUBACK 报文用于订阅,而 UNSUBSCRIBE 和 UNSUBACK 用于取消订阅。要订阅或取消订阅的主题过滤器列表位于相应报文的 Payload 中。SUBSCRIBE 报文中的每个主题过滤器都与一组订阅选项相关联。

SUBACK 和 UNSUBACK 报文中的 Reason Code 表示请求结果,它是一个列表,与请求报文中对应的主题过滤器一一对应。

参考链接:

  1. https://www.emqx.com/en/blog/mqtt-5-0-control-packets-03-subscribe-unsubscribe
  2. https://www.hivemq.com/blog/mqtt-essentials-part-4-mqtt-publish-subscribe-unsubscribe/
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Hello工控 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Sample样例
  • SUBSCRIBE Packet Structure
    • Variable Header 变量头
    • Payload 载荷
  • SUBACK Packet Structure SUBACK 数据包结构
    • Variable Header 变量头
  • UNSUBSCRIBE Packet Structure UNSUBSCRIBE 数据包结构
    • Payload 载荷
    • UNSUBSCRIBE 报文的负载包含一个或多个客户端希望退订的主题过滤器。这些主题过滤器也是 UTF-8 编码的字符串,多个主题过滤器紧密相连。
  • UNSUBACK Packet Structure UNSUBACK 数据包结构
    • Variable Header 变量头
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档