MQTT中文站
  • 首页
  • MQTT 学习
    • MQTT 入门
    • MQTT 进阶
    • MQTT 编程
    • MQTT 实例
    • MQTT 要点
    • MQTT5 要点
    • MQTT 工具
    • MQTT 客户端库
    • MQTT 服务器
    • Zigbee2MQTT
    • Sparkplug
    • Home Assistant
    • Node-RED
      • Node-RED 安装部署
      • Node-RED 用户指南
      • Node-RED 创建节点
      • Node-RED 示例教程
      • Node-RED 开发流程
      • Node-RED 接口参考
      • Node-RED 配置模板
      • Node-RED 常见问题
  • MQTT 规范
    • MQTT 5 规范
    • MQTT 3.1.1 规范
    • MQTT 3.1 规范
    • MQTT-SN v1.2规范
    • Sparkplug® v3.0.0规范
  • 产品中心
  • 解决方案
    • 环境监测
    • 工业制造
    • 智慧水利
    • 水利管网
    • 积水监测
    • 综合管廊
    • 档案库房
    • 交通物流
    • 智慧城市
    • 智慧农业
    • 智慧养殖
    • 能源电力
    • 石油石化
    • 智能家居
    • 物联网
    • 汽车与出行
  • 使用文档
  • MQTT 云平台
  • 登录
  • 注册
首页 MQTT 教程 MQTT 5.0 Reason Code 深入解析:故障排除与更精细的错误处理

MQTT 5.0 Reason Code 深入解析:故障排除与更精细的错误处理

1 年前 • MQTT 教程

在MQTT 5.0中,Reason Code的引入为客户端和服务端提供了更详细的反馈机制。这些代码不仅帮助诊断连接问题,还让开发者能够更精确地处理各种异常情况。与MQTT 3.1.1相比,MQTT 5.0扩展了Reason Code的范围和应用,使得错误处理更加灵活和详细。

MQTT 3.1.1与MQTT 5.0中的Reason Code对比

在MQTT 3.1.1版本中,Reason Code的使用相对有限,仅在CONNACK和SUBACK报文中提供了一些基本的错误代码。这些代码的范围和细节都较为有限,使得开发者在诊断和处理问题时可能会遇到一些挑战。

而MQTT 5.0则大幅扩展了Reason Code的数量和应用场景,引入了43个不同的代码,覆盖了连接、发布、订阅、取消订阅等多种操作的成功与失败情况。这些代码被分为两大类:小于0x80的表示操作成功,等于或大于0x80的表示操作失败。

MQTT 5.0 Reason Code速查表

为了便于理解和应用,以下是一些常见MQTT 5.0 Reason Codes的速查表,包括它们的含义和使用场景:

Reason CodeNamePacketsDetails
0x00SuccessCONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK, AUTH这个 Reason Code 可以用在所有存在 Reason Code 的报文中,例如 CONNACK、DISCONNECT 报文等等。它通常用于表示成功,比如连接成功、取消订阅成功、消息接收成功和认证成功等等。
0x00Normal disconnectionDISCONNECT在 DISCONNECT 报文中,0 则表示连接正常断开,这种情况下遗嘱消息不会被发布。
0x00Granted QoS 0SUBACK0,1,2 在 SUBACK 这个订阅确认报文中,用来指示订阅结果,它们都表示订阅成功,同时向订阅端指示最终被授予的最大 QoS 等级,0,1,2 正好对应了三个 QoS 等级。 这是因为服务端最终授予的最大 QoS 等级,可能小于订阅时请求的最大 QoS 等级。比如订阅时请求的最大 QoS 等级是 2,但服务端最高仅支持 QoS 1 等等。
0x01Granted QoS 1SUBACK-
0x02Granted QoS 2SUBACK-
0x04Disconnect with Will MessageDISCONNECT仅用于 DISCONNECT 报文,适用于客户端希望正常断开连接但服务端仍然需要发布遗嘱消息的情况,比如客户端希望会话过期时可以对外发出通知。
0x10No matching subscribersPUBACK, PUBREC这个 Reason Code 用于向发送方指示,消息已经收到,但是当前没有匹配的订阅者,所以只有服务端可以使用这个 Reason Code。我们可以通过收到 Reason Code 为 0x10 的响应报文得知当前没有人会收到自己的消息,但是不能通过没有收到 Reason Code 为 0x10 的响应报文来假定所有人都会收到自己的消息,除非最多只会存在一个订阅者。但需要注意,没有匹配的订阅者时使用 0x10 替代 0x00,并不是一个必须实现的行为,这取决于服务端的具体实现。
0x11No subscription existedUNSUBACK仅用于 UNSUBACK 报文,表示取消订阅时没有发现匹配的订阅。
0x18Continue authenticationAUTH仅用于 AUTH 报文,表示继续认证,通过这个 Reason Code,客户端和服务端之间可以进行任意次数的 AUTH 报文交换,以满足不同的认证方法的需要。
0x19Re-authenticateAUTH仅用于 AUTH 报文,在增强认证成功后客户端可以随时通过发送 Reason Code 为 0x19 的 AUTH 报文发起重新认证。重新认证期间,其他报文收发会正常继续,如果重新认证失败,连接就会被关闭。
0x80Unspecified errorCONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT表示未指明的错误。当一方不希望向另一方透露错误的具体原因,或者协议规范中没有能够匹配当前情况的 Reason Code 时,那么它可以在报文中使用这个 Reason Code。
0x81Malformed PacketCONNACK, DISCONNECT当收到了无法根据协议规范正确解析的控制报文时,接收方需要发送 Reason Code 为 0x81 的 DISCONNECT 报文来断开连接。如果是 CONNECT 报文存在问题,那么服务端应该使用 CONNACK 报文。当控制报文中出现固定报头中的保留位没有按照协议要求置 0、QoS 被指定为 3、UTF-8 字符串中包含了一个空字符等等这些情况时,都将被认为是一个畸形的报文。
0x82Protocol ErrorCONNACK, DISCONNECT在控制报文被按照协议规范解析后检测到的错误,比如包含协议不允许的数据,行为与协议要求不符等等,都会被认为是协议错误。接收方需要发送 Reason Code 为 0x81 的 DISCONNECT 报文来断开连接。如果是 CONNECT 报文存在问题,那么服务端应该使用 CONNACK 报文。常见的协议错误包括,客户端在一个连接内发送了两个 CONNECT 报文、一个报文中包含了多个相同的属性,以及某个属性被设置成了一个协议不允许的值等等。但是当我们有其他更具体的 Reason Code 时,就不会使用 0x81 (Malformed Packet) 或者 0x82 (Protocol Error) 了。例如,服务端已经声明自己不支持保留消息,但客户端仍然向服务端发送保留消息,这本质上也属于协议错误,但我们会选择使用 0x9A (Retain not supported) 这个能够更清楚指明错误原因的 Reason Code。
0x83Implementation specific errorCONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT报文有效,但是不被当前接收方的实现所接受。
0x84Unsupported Protocol VersionCONNACK仅用于 CONNACK 报文。对于支持了 MQTT 5.0 的服务端来说,如果不支持客户端当前使用的 MQTT 协议版本,或者客户端指定了一个错误的协议版本或协议名。例如,客户端将协议版本设置为 6,那么服务端可以发送 Reason Code 为 0x84 的 CONNACK 报文,表示不支持该协议版本并且表明自己 MQTT 服务端的身份,然后关闭网络连接。当然服务端也可以选择直接关闭网络连接,因为使用 MQTT 3.1 或 3.1.1 的 MQTT 客户端可能并不能理解 0x84 这个 Reason Code 的含义。这两个版本都是在 CONNACK 报文使用 0x01 来表示不支持客户端指定的协议版本。
0x85Client Identifier not validCONNACK仅用于 CONNACK 报文,表示 Client ID 是有效的字符串,但是服务端不允许。可能的情形有 Clean Start 为 0 但 Client ID 为空、或者 Client ID 超出了服务端允许的最大长度等等。
0x86Bad User Name or PasswordCONNACK仅用于 CONNACK 报文,表示客户端使用了错误的用户名或密码,这也意味着客户端将被拒绝连接。
0x87Not authorizedCONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT当客户端使用 Token 认证或者增强认证时,使用 0x87 来表示客户端没有被授权连接会比 0x86 更加合适。当客户端进行发布、订阅等操作时,如果没有通过服务端的授权检查,那么服务端也可以在 PUBACK 等应答报文中指定 0x87 这个 Reason Code 来指示授权结果。
0x88Server unavailableCONNACK仅用于 CONNACK 报文,向客户端指示当前服务端不可用。比如当前服务端认证服务异常无法接入新客户端等等。
0x89Server busyCONNACK, DISCONNECT向客户端指示服务端正忙,请稍后再试。
0x8ABannedCONNACK仅用于 CONNACK 报文,表示客户端被禁止登录。例如服务端检测到客户端的异常连接行为,所以将这个客户端的 Client ID 或者 IP 地址加入到了黑名单列表中,又或者是后台管理人员手动封禁了这个客户端,当然以上这些通常需要视服务端的具体实现而定。
0x8BServer shutting downDISCONNECT仅用于 DISCONNECT 报文,并且只有服务端可以使用。如果服务端正在或即将关闭,它可以通过主动发送 Reason Code 为 0x8B 的 DISCONNECT 报文的方式告知客户端连接因为服务端正在关闭而被终止。这可以帮助客户端避免在连接关闭后继续向此服务端发起连接请求。
0x8CBad authentication methodCONNACK, DISCONNECT当服务端不支持客户端指定的增强认证方法,或者客户端在重新认证时使用了和之前认证不同的认证方法时,那么服务端就会发送 Reason Code 为 0x8C 的 CONNACK 或者 DISCONNECT 报文。
0x8DKeep Alive timeoutDISCONNECT仅用于 DISCONNECT 报文,并且只有服务端可以使用。如果客户端没能在 1.5 倍的 Keep Alive 时间内保持通信,服务端将会发送 Reason Code 为 0x8D 的 DISCONNECT 报文然后关闭网络连接。
0x8ESession taken overDISCONNECT仅用于 DISCONNECT 报文,并且只有服务端可以使用。当客户端连接到服务端时,如果服务端中已经存在使用相同 Client ID 的客户端连接,那么服务端就会向原有的客户端发送 Reason Code 为 0x8E 的 DISCONNECT 报文,表示会话被新的客户端连接接管,然后关闭原有的网络连接。不管新的客户端连接中的 Clean Start 是 0 还是 1,服务端都会使用这个 Reason Code 向原有客户端指示会话被接管。
0x8FTopic Filter invalidSUBACK, UNSUBACK, DISCONNECT主题过滤器的格式正确,但是不被服务端接受。比如主题过滤器的层级超过了服务端允许的最大数量限制,或者主题过滤器中包含了空格等不被当前服务端接受的字符。
0x90Topic Name invalidCONNACK, PUBACK, PUBREC, DISCONNECT主题名的格式正确,但是不被客户端或服务端接受。
0x91Packet Identifier in usePUBACK, PUBREC, SUBACK, UNSUBACK表示收到报文中的 Packet ID 正在被使用,例如发送方发送了一个 Packet ID 为 100 的 QoS 1 消息,但是接收方认为当前有一个使用相同 Packet ID 的 QoS 2 消息还没有按成它的报文流程。这通常意味着当前客户端和服务端之前的会话状态不匹配,可能需要通过设置 Clean Start 为 1 重新连接来重置会话状态。
0x92Packet Identifier not foundPUBREL, PUBCOMP表示未找到对应的 Packet ID,这只会在 QoS 2 的报文交互流程中发生。比如当接收方回复 PUBREC 报文时,发送方未找到使用相同 Packet ID 的等待确认的 PUBLISH 报文,或者当发送方发送 PUBREL 报文时,接收方未找到使用相同 Packet ID 的 PUBREC 报文。这通常意味着当前客户端和服务端之间的会话状态不匹配,可能需要通过设置 Clean Start 为 1 重新连接来重置会话状态。
0x93Receive Maximum exceededDISCONNECT仅用于 DISCONNECT 报文,表示超出了接收最大值。MQTT 5.0 增加了流控机制,客户端和服务端在连接时通过 Receive Maximum 属性约定它们愿意并发处理的可靠消息数(QoS > 0)。所以一旦发送方发送的没有完成确认的消息超过了这一数量限制,接收方就会发送 Reason Code 为 0x93 的 DISCONNECT 报文然后关闭网络连接。
0x94Topic Alias invalidDISCONNECT仅用于 DISCONNECT 报文,表示主题别名不合法。如果 PUBLISH 报文中的主题别名值为 0 或者大于连接时约定的最大主题别名,接收方会将此视为协议错误,它将发送 Reason Code 为 0x94 的 DISCONNECT 报文然后关闭网络连接。
0x95Packet too largeCONNACK, DISCONNECT用于表示报文超过了最大允许长度。客户端和服务端各自允许的最大报文长度,可以在 CONNECT 和 CONNACK 报文中通过 Maximum Packet Size 属性约定。当一方发送了过大的报文,那么另一方将发送 Reason Code 为 0x95 的 DISCONNECT 报文,然后关闭网络连接。由于客户端可以在连接时设置遗嘱消息,因此 CONNECT 报文也有可能超过服务端能够处理的最大报文长度限制,此时服务端需要在 CONNACK 报文中使用这个 Reason Code。
0x96Message rate too highDISCONNECT仅用于 DISCONNECT 报文,表示超过了允许的最大消息发布速率。需要注意它与 Quota exceeded 的区别,Message rate 限制消息的发布速率,比如每秒最高可发布多少消息,Quota 限制的是资源的配额,比如客户端每天可以发布的消息数量,但客户端可能在一小时内耗尽它的配额。
0x97Quota exceededCONNACK, PUBACK, PUBREC, SUBACK, DISCONNECT用于表示超出了配额限制。服务端可能会对发布端的发送配额进行限制,比如每天最多为其转发 1000 条消息。当发布端的配额耗尽,服务端就会在 PUBACK 等确认报文中使用这个 Reason Code 提醒对方。另一方面,服务端还可能限制客户端的连接数量和订阅数量,当超出这一限制时,服务端就会通过 CONNACK 或者 SUBACK 报文向客户端指示当前超出了配额。一些严格的客户端和服务端,在发现对端超出配额时,可能会选择发送 DISCONNECT 报文然后关闭连接。
0x98Administrative actionDISCONNECT仅用于 DISCONNECT 报文,向客户端指示连接因为管理操作而被关闭,例如运维人员在后台踢除了这个客户端连接等等。
0x99Payload format invalidCONNACK, PUBACK, PUBREC, DISCONNECT当消息中包含 Payload Format Indicator 属性时,接收方可以检查消息中 Payload 的格式与该属性是否匹配。如果不匹配,接收方需要发送 Reason Code 为 0x99 的确认报文。一些严格的客户端或者服务器,可能会直接发送 DISCONNECT 报文然后关闭网络连接。如果是 CONNECT 报文中的遗嘱消息存在问题,服务端将发送 Reason Code 为 0x99 的 CONNACK 报文然后关闭网络连接。
0x9ARetain not supportedCONNACK, DISCONNECT当服务端不支持保留消息,但是客户端发送了保留消息时,服务端就会向它发送 Reason Code 为 0x9A 的 DISCONNECT 报文然后关闭网络连接。由于客户端还可以在连接时将遗嘱消息设置为保留消息,所以服务端也可能在 CONNACK 报文中使用这个 Reason Code。
0x9BQoS not supportedCONNACK, DISCONNECT用于表示不支持当前的 QoS 等级。如果客户端在消息(包括遗嘱消息)中指定的 QoS 大于服务端支持的最大 QoS,服务端将会发送 Reason Code 为 0x9B 的 DISCONNECT 或者 CONNACK 报文然后关闭网络连接。在大部份情况下,这个 Reason Code 都是由服务端使用。但是在客户端收到不是来自订阅的消息,并且消息的 QoS 大于它支持的最大 QoS 时,它也会发送 Reason Code 为 0x9B 的 DISCONNECT 报文然后关闭网络连接。这种情况通常意味着服务端的实现可能存在问题。
0x9CUse another serverCONNACK, DISCONNECT服务端在 CONNACK 或者 DISCONNECT 报文中通过这个 Reason Code 告知客户端应该临时切换到另一个服务端。如果另一个服务端不是客户端已知的,那么这个 Reason Code 还需要配合 Server Reference 属性一起使用,以告知客户端新的服务端的地址。
0x9DServer movedCONNACK, DISCONNECT服务端在 CONNACK 或者 DISCONNECT 报文中通过这个 Reason Code 告知客户端应该永久切换到另一个服务端。如果另一个服务端不是客户端已知的,那么这个 Reason Code 还需要配合 Server Reference 属性一起使用,以告知客户端新的服务端的地址。
0x9EShared Subscriptions not supportedSUBACK, DISCONNECT当服务端不支持共享订阅,但是客户端尝试建立共享订阅时,服务端可以发送 Reason Code 为 0x9E 的 SUBACK 报文拒绝这次订阅请求,也可以直接发送 Reason Code 为 0x9E 的 DISCONNECT 报文然后关闭网络连接。
0x9FConnection rate exceededCONNACK, DISCONNECT用于表示客户端已超过连接速率限制。服务端可以对客户端的连接速率做出限制,客户端连接过快时,服务端可以发送 Reason Code 为 0x9F 的 CONNACK 报文来拒绝新的连接。当然这并不是绝对的情况,考虑到不是所有的客户端都会等待一段时间再重新发起连接,一些服务端实现可能会选择暂时挂起连接而不是返回 CONNACK。
0xA0Maximum connect timeDISCONNECT仅用于 DISCONNECT 报文,并且只有服务端可以使用。出于安全性的考虑,服务端可以限制单次授权中客户端的最大连接时间,比如在使用 JWT 认证时,客户端连接不应在 JWT 过期后继续保持。这种情况下,服务端可以发送 Reason Code 为 0xA0 的 DISCONNECT 报文,向客户端指示连接因为超过授权的最大连接时间而被关闭。客户端可以在收到包含这个 Reason Code 的 DISCONNECT 报文后,重新获取认证凭据然后再次请求连接。
0xA1Subscription Identifiers not supportedSUBACK, DISCONNECT当服务端不支持订阅标识符,但是客户端的订阅请求中包含了订阅标识符时,服务端可以发送 Reason Code 为 0xA1 的 SUBACK 报文拒绝这次订阅请求,也可以直接发送 Reason Code 为 0xA1 的 DISCONNECT 报文然后关闭网络连接。
0xA2Wildcard Subscriptions not supportedSUBACK, DISCONNECT当服务端不支持通配符订阅,但是客户端的订阅请求中包含了主题通配符时,服务端可以发送 Reason Code 为 0xA2 的 SUBACK 报文拒绝这次订阅请求,也可以直接发送 Reason Code 为 0xA2 的 DISCONNECT 报文然后关闭网络连接。

使用Reason Code的注意事项

  • 精确处理错误:利用MQTT 5.0的Reason Code,开发者可以更精确地诊断和处理连接或操作失败的原因。
  • 优化用户体验:通过根据不同的错误代码提供更具体的错误信息或采取相应的恢复措施,可以优化最终用户的体验。
  • 日志记录:在开发和调试过程中,记录包含Reason Code的操作可以帮助快速定位问题。

MQTT 5.0的Reason Code为MQTT协议的使用提供了更强大的错误处理能力,使得开发者能够构建更健壮、更可靠的MQTT应用。

打赏赞微海报分享
disconnect mqtt qos 报文交换 软件

什么是 MQTT 遗嘱消息?MQTT 遗嘱消息如何运作?

如何用 MQTT 5.0 的消息过期间隔特性提升应用性能

猜你喜欢

智能会议电子门牌产品说明书

智能会议电子门牌产品说明书

04/03
2025
改善基础设施:HiveMQ如何推动智能城市发展

改善基础设施:HiveMQ如何推动智能城市发展

08/07
2024
为什么企业选择全托管HiveMQ云进行MQTT部署

为什么企业选择全托管HiveMQ云进行MQTT部署

07/01
2024

回复

抢沙发咯
  • 解决方案
    • 智能家居
    • 汽车与出行
    • 工业制造
    • 能源电力
    • 石油石化
    • 交通物流
    • 零售
  • 学习
    • MQTT 规范
    • MQTT 教程
    • MQTT 软件
    • MQTT 客户端库
    • MQTT 服务器
    • 工具和应用程序
  • 关于我们
    • 了解创科慧仁
    • 加入创科慧仁
    • 投资者关系
    • 新闻动态
    • 合作伙伴
    • 联系我们
  • 友情链接
    • Modbus中文网
    • 跳动符号官网
    • 物联网世界
    • RFID世界网
    • 深圳物联网协会
    • isoftstone软通动力
    • 中国发展战略学研究会
    • B.P商业伙伴
  • 在线客服
  • 全国客户服务热线
    4006909885
  • 官方公众号
  • 联系邮箱
    contact@mqtt.cn
Copyright © 2025 MQTT中文站. All rights reserved.Designed by nicetheme. 京ICP备20029519号
在线客服

微信咨询

微信咨询

4006909885

服务热线 7*24小时

电话咨询
  • 首页
  • MQTT 学习
    • MQTT 入门
    • MQTT 进阶
    • MQTT 编程
    • MQTT 实例
    • MQTT 要点
    • MQTT5 要点
    • MQTT 工具
    • MQTT 客户端库
    • MQTT 服务器
    • Zigbee2MQTT
    • Sparkplug
    • Home Assistant
    • Node-RED
  • MQTT 规范
    • MQTT 5 规范
    • MQTT 3.1.1 规范
    • MQTT 3.1 规范
    • MQTT-SN v1.2规范
    • Sparkplug® v3.0.0规范
  • 产品中心
  • 解决方案
    • 环境监测
    • 工业制造
    • 智慧水利
    • 水利管网
    • 积水监测
    • 综合管廊
    • 档案库房
    • 交通物流
    • 智慧城市
    • 智慧农业
    • 智慧养殖
    • 能源电力
    • 石油石化
    • 智能家居
    • 物联网
    • 汽车与出行
  • 使用文档
  • MQTT 云平台
  • 登录
  • 注册
string(5) "2.0.0"