MQTT 5.0 报文解析 05:DISCONNECT

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 在 MQTT 中,客户端和服务端可以在断开网络连接前向对端发送一个 DISCONNECT 报文,来指示连接关闭的原因。客户端发送的 DISCONNECT 报文还可以影响服务端在连接断开后的行为,例如是否发送遗嘱消息,是否更新会话过期间隔。

欢迎阅读 MQTT 5.0 报文系列的第五篇文章。在上一篇中,我们已经介绍了 MQTT 5.0 的 PINGREQ 和 PINGRESP 报文。现在,我们将介绍下一个控制报文:DISCONNECT。

在 MQTT 中,客户端和服务端可以在断开网络连接前向对端发送一个 DISCONNECT 报文,来指示连接关闭的原因。客户端发送的 DISCONNECT 报文还可以影响服务端在连接断开后的行为,例如是否发送遗嘱消息,是否更新会话过期间隔。

DISCONNECT 报文示例

我们使用 MQTTX CLI向公共 MQTT 服务器发起一个指定了 Client ID 的客户端连接,并将 --reconnect-period 设置为 0 来禁用自动重连,然后在另一个终端中运行相同的命令创建一个使用相同 Client ID 的连接。

整个过程使用 Wireshark 工具来抓取在客户端与服务器之间往返的 MQTT 报文,Linux 环境可以使用 tcpdump 命令抓取报文,然后导入至 Wireshark 分析。

以下命令将创建一个 Client ID 为 mqtt-892324 的客户端连接,为了避免 Client ID 与别人重复,建议将它改为其他随机字符串:

mqttx conn --hostname broker.emqx.io --mqtt-version 5 --client-id mqtt-892324 \ --reconnect-period 0

在我们发起第二个连接后,Wireshark 将捕获到公共 MQTT 服务器返回给第一个连接的 DISCONNECT 报文:

e0 02 8e 00

这四个十六进制字节,对应着以下报文内容:

DISCONNECT Packet.png

通过下文对 DISCONNECT 报文结构的介绍,你将了解到如何从原始的报文数据中提取你想要的信息。

DISCONNECT 报文结构

固定报头

固定报头首字节的高 4 位,即报文类型字段的值为 14(0b1110),低 4 位全部为 0,表示这是一个 DISCONNECT 报文。

Fixed Header.png

可变报头

DISCONNECT 报文的可变报头按顺序包含以下字段:

Viriable Header.png

  • 原因码(Reason Code):一个单字节的无符号整数,用于向对端指示连接断开的原因。下表列出了在 DISCONNECT 报文中常见的 Reason Code,完整列表可参阅 MQTT 5.0 Reason Code 速查表。
Value Reason Code Name Sent By Description
0x00 Normal disconnection 客户端、服务端 表示连接正常关闭,因此服务端不会发布遗嘱消息。
0x04 Disconnect with Will Message 客户端 连接正常关闭,但客户端希望服务端仍然发布遗嘱消息。
0x81 Malformed Packet 客户端、服务端 表示收到了无法按照协议规范正确解析的控制报文,在 MQTT 中我们将这类报文称为畸形报文。
0x82 Protocol Error 客户端、服务端 协议错误通常指控制报文在按照协议规范解析以后才能发现的错误,包括包含协议不允许的数据、行为与协议要求不符等等。比如客户端在一个连接内发送了两个 CONNECT 报文。
0x8D Keep Alive timeout 服务端 服务端在超过 1.5 倍的 Keep Alive 时间内没有收到任何报文,因此关闭了连接。
0x8E Session taken over 服务端 另一个更新的使用了且相同的 Client ID 的连接被建立,导致服务端关闭了此连接。
0x93 Receive Maximum exceeded 客户端、服务端 表示对端同时发送的 QoS > 0 的 PUBLISH 报文数量超过了连接时设置的接收最大值。
0x94 Topic Alias invalid 客户端、服务端 表示主题别名不合法。比如 PUBLISH 报文中的主题别名值为 0 或者大于连接时约定的最大主题别名。
0x95 Packet too large 客户端、服务端 表示报文超过了连接时约定的最大允许长度。
0x98 Administrative action 客户端、服务端 表示连接因为管理操作而被关闭,比如运维人员在服务端后台踢除了客户端连接。
0x9C Use another server 服务端 表示客户端应该临时切换到另一个服务器。如果另一个服务器不是客户端已知的,那么还需要配合 Server Reference 属性一起使用,以告知客户端新的服务端的地址。
0x9D Server moved 服务端 表示客户端应该永久切换到另一个服务器。如果另一个服务器不是客户端已知的,那么还需要配合 Server Reference 属性一起使用,以告知客户端新的服务端的地址。
  • 属性(Properties):下表列出了 DISCONNECT 报文的所有可用属性。
Identifier Property Name Sent By Type
0x11 Session Expiry Interval 客户端 四字节整数
0x1F Reason String 客户端、服务端 UTF-8 编码的字符串
0x26 User Property 客户端、服务端 UTF-8 字符串对
0x1C Server Reference 服务端 UTF-8 编码的字符串

与之前介绍的其他报文不同,客户端和服务端在 DISCONNECT 报文中可以使用的原因码和属性是不同的,例如 Session Expiry Interval 属性就只能在客户端发送的 DISCONNECT 报文中使用,所以我们在上面的列表中均列出了它们的可用范围。

有效载荷

DISCONNECT 报文不包含有效载荷。

总结

客户端和服务端都可以发送 DISCONNECT 报文,表示准备断开网络连接,报文中的原因码可以向接收方指示连接关闭的原因。当 MQTT 连接意外断开时,我们可以优先查看是否收到了 DISCONNECT 报文以及报文中原因码的值。

虽然客户端和服务端在 DISCONNECT 报文中可以用的原因码和属性存在差异,但我们并不需要强行去记忆它们。它们通常都和对应的机制与行为相关,例如遗嘱消息只会由服务端发布,所以希望连接正常关闭但对端仍要发布遗嘱消息的原因码 0x04,也会被客户端使用。

以上就是对 DISCONNECT 报文的介绍,在下一篇文章中我们将介绍 MQTT 5.0 增强认证特性所使用的 AUTH 报文,它也是 MQTT 中最后一个报文类型。

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
3月前
|
消息中间件 Java Apache
RocketMQ消息回溯实践与解析
在分布式系统和高并发应用的开发中,消息队列扮演着至关重要的角色,而RocketMQ作为阿里巴巴开源的一款高性能消息中间件,以其高吞吐量、高可用性和灵活的配置能力,在业界得到了广泛应用。本文将围绕RocketMQ的消息回溯功能进行实践与解析,分享工作学习中的技术干货。
91 4
|
1月前
|
消息中间件 存储 Java
RocketMQ文件刷盘机制深度解析与Java模拟实现
【11月更文挑战第22天】在现代分布式系统中,消息队列(Message Queue, MQ)作为一种重要的中间件,扮演着连接不同服务、实现异步通信和消息解耦的关键角色。Apache RocketMQ作为一款高性能的分布式消息中间件,广泛应用于实时数据流处理、日志流处理等场景。为了保证消息的可靠性,RocketMQ引入了一种称为“刷盘”的机制,将消息从内存写入到磁盘中,确保消息持久化。本文将从底层原理、业务场景、概念、功能点等方面深入解析RocketMQ的文件刷盘机制,并使用Java模拟实现类似的功能。
41 3
|
2月前
|
消息中间件 存储 监控
RocketMQ消息重试机制解析!
RocketMQ消息重试机制解析!
RocketMQ消息重试机制解析!
|
4月前
|
消息中间件 开发者
【RabbitMQ深度解析】Topic交换器与模式匹配:掌握消息路由的艺术!
【8月更文挑战第24天】在消息队列(MQ)体系中,交换器作为核心组件之一负责消息路由。特别是`topic`类型的交换器,它通过模式匹配实现消息的精准分发,适用于发布-订阅模式。不同于直接交换器和扇形交换器,`topic`交换器支持更复杂的路由策略,通过带有通配符(如 * 和 #)的模式字符串来定义队列与交换器间的绑定关系。
81 2
EMQ
|
6月前
|
安全 开发工具 数据安全/隐私保护
MQTT 5.0 报文解析 06:AUTH
MQTT 5.0 引入了增强认证特性,它使 MQTT 除了简单密码认证和 Token 认证以外,还能够支持质询/响应风格的认证。为了实现这一点,它在原先 CONNECT 和 CONNACK 报文的基础上,又引入了 AUTH 报文来实现任意多次的认证数据交换,以支持各种不同类型的认证机制,例如 SCRAM、Kerberos 认证等等。
EMQ
311 7
MQTT 5.0 报文解析 06:AUTH
|
4月前
|
消息中间件 Java RocketMQ
微服务架构师的福音:深度解析Spring Cloud RocketMQ,打造高可靠消息驱动系统的不二之选!
【8月更文挑战第29天】Spring Cloud RocketMQ结合了Spring Cloud生态与RocketMQ消息中间件的优势,简化了RocketMQ在微服务中的集成,使开发者能更专注业务逻辑。通过配置依赖和连接信息,可轻松搭建消息生产和消费流程,支持消息过滤、转换及分布式事务等功能,确保微服务间解耦的同时,提升了系统的稳定性和效率。掌握其应用,有助于构建复杂分布式系统。
72 0
|
5月前
|
网络协议 安全 网络安全
解析IPv6报文结构
【7月更文挑战第1天】IPv6报文结构包括基本头和可选的扩展头,基本头固定40字节,含8个字段,不支持分片,提升了处理效率。扩展头灵活处理选项,长度为8字节的倍数,可包含如路由、分片、认证和安全封装等信息。多个扩展头按特定顺序排列,目的选项头可出现两次。
|
6月前
|
消息中间件 存储 运维
RocketMQ与Kafka深度对比:特性与适用场景解析
RocketMQ与Kafka深度对比:特性与适用场景解析
|
6月前
|
消息中间件 自然语言处理 负载均衡
RabbitMQ揭秘:轻量级消息队列的优缺点全解析
**RabbitMQ简介** RabbitMQ是源自电信行业的消息中间件,支持AMQP协议,提供轻量、快速且易于部署的解决方案。它拥有灵活的路由配置,广泛的语言支持,适用于异步处理、负载均衡、日志收集和微服务通信等场景。然而,当面临大量消息堆积或高吞吐量需求时,性能可能会下降,并且扩展和开发成本相对较高。
299 0
|
2月前
|
消息中间件 JSON Java
开发者如何使用轻量消息队列MNS
【10月更文挑战第19天】开发者如何使用轻量消息队列MNS
98 5

推荐镜像

更多
下一篇
DataWorks