MQTT 5.0 Código de motivo Introducción y hoja de referencia de uso

Código de razón

La función principal del código de motivo en MQTT es proporcionar comentarios más detallados para el cliente y el servidor. Por ejemplo, podemos retroalimentar el código de razón correspondiente al nombre de usuario o contraseña incorrectos al cliente en el mensaje CONNACK, para que el cliente pueda saber la razón por la que no puede conectarse.

Código de motivo en MQTT 3.1.1

Aunque MQTT 3.1.1 ya es compatible con el código de motivo, no define demasiados códigos de motivo disponibles.

Entre los dos únicos mensajes que admiten el código de motivo, el mensaje CONNACK tiene solo 5 códigos de motivo que se usan para indicar la falla, y el mensaje SUBACK tiene solo un código de motivo que se usa para indicar la falla, que no puede indicar más la razón de la falla de suscripción. . Para las operaciones que no admiten Reason Code, como publicar y cancelar la suscripción, ni siquiera sabemos si la operación es exitosa o no. Esto no solo es muy poco amigable para el desarrollo y la depuración, sino que tampoco es propicio para lograr un código robusto.

Código de motivo en MQTT 5.0

Por lo tanto, en MQTT 5.0, los códigos de motivo disponibles se amplían a 43 y se especifica un código de motivo inferior a 0x80 para indicar el éxito, y se utiliza un código de motivo mayor o igual a 0x80 para indicar un error. Y ya no como MQTT 3.1.1, un código de razón inferior a 0x80 también puede indicar una falla. Esto hace que sea más fácil para el cliente saber si la operación fue exitosa.

Además, los mensajes que admiten el código de motivo en MQTT 5.0 también se extienden a: CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, UNSUBACK, DISCONNECT y AUTH. Ahora, no solo podemos saber si la publicación del mensaje es exitosa, sino también conocer el motivo de la falla, por ejemplo, actualmente no hay un suscriptor que coincida, o no hay derecho a publicar un mensaje en este tema, y ​​así sucesivamente.

Códigos de motivo en MQTT 3.1.1 Códigos de razón en MQTT 5.0
CONNACK
DESCONECTAR
REPUESTOS
PUBREC
PUBLICO
PUBCOMP
VOLVER
UNSUBACK
AUTORIZACIÓN

La mayoría de los paquetes solo contienen un código de motivo, excepto SUBACK y UNSUBACK. Esto se debe a que los mensajes SUBSCRIBE y UNSUBSCRIBE pueden contener varios filtros de tema, y ​​cada filtro de tema debe tener un código de motivo correspondiente para indicar el resultado de su operación, por lo que los mensajes SUBACK y UNSUBACK también deben poder contener varios códigos de motivo. Esta es la razón por la que los códigos de motivo de otros paquetes se encuentran en el encabezado de la variable, mientras que los códigos de motivo de SUBACK y UNSUBACK se encuentran en la carga útil.

paquetes MQTT

En la hoja de trucos del código de motivo al final de este artículo, explicamos en detalle el significado y los escenarios de uso de cada código de motivo en MQTT 5.0, y puede comprobarlo usted mismo.

Indica al cliente por qué se cortó la conexión

En MQTT 3.1 y 3.1.1, los mensajes DISCONNECT solo pueden ser emitidos por clientes. Por lo tanto, cuando el cliente viola ciertas restricciones, el servidor solo puede cerrar la conexión de red directamente, pero no puede pasar más información al cliente, lo que dificulta investigar la causa de la desconexión.

En MQTT 5.0, el servidor puede enviar un mensaje de DESCONEXIÓN al cliente antes de cerrar la conexión de red, y el cliente puede usar el código de motivo en el mensaje de DESCONEXIÓN para comprender el motivo por el cual se desconectó la conexión, como que el mensaje es demasiado grande, el servidor ocupado esperando.

Cadena de motivo

Reason String es un complemento de Reason Code en MQTT 5.0, que es una cadena legible por humanos diseñada para el diagnóstico. Aunque el código de razón ya puede indicar la causa de la mayoría de los errores, para los desarrolladores o el personal de operación y mantenimiento, aún puede faltar información contextual más intuitiva.

Por ejemplo, cuando el servidor le indica al cliente que el filtro de tema no es válido (0x8F) a través del código de motivo, el desarrollador aún no tiene forma de saber el motivo específico. ¿Hay demasiados niveles de tema? ¿O contiene caracteres que no son aceptados por el servidor? Y si el servidor puede devolver una cadena de motivo con un contenido similar a "La cantidad de niveles de tema excede el límite, el máximo es 10", entonces el desarrollador pronto podrá conocer el motivo y realizar ajustes.

En el uso real, el contenido de Reason String depende de la implementación específica del cliente y el servidor, por lo que un receptor implementado correctamente no debe intentar analizar el contenido de Reason String. El uso recomendado incluye, entre otros, el uso de Reason cuando se produce una excepción. se arroja String, o escríbalo en el registro.

Finalmente, Reason String es una función opcional, y si recibir Reason String depende de si el par lo admite.

Hoja de referencia del código de motivo de MQTT 5.0

Código de razón Nombre Paquetes Detalles
0x00 Éxito CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, UNSUBACK, AUTH Este código de motivo se puede utilizar en todos los mensajes con código de motivo, como mensajes CONNACK, DISCONNECT, etc. Por lo general, se usa para indicar el éxito, como conexión exitosa, cancelación de suscripción exitosa, recepción de mensajes exitosa, autenticación exitosa, etc.
0x00 Desconexión normal DESCONECTAR En el mensaje DISCONNECT, 0 significa que la conexión se desconecta normalmente, en cuyo caso no se publicará el mensaje de voluntad.
0x00 QoS concedido 0 VOLVER 0, 1, 2 se utilizan para indicar el resultado de suscripción en el mensaje de confirmación de suscripción de SUBACK, todos indican que la suscripción es exitosa, y al mismo tiempo indican el nivel máximo de QoS otorgado al suscriptor. 0, 1 y 2 corresponden a tres grados QoS. Esto se debe a que el nivel máximo de QoS otorgado por el servidor puede ser menor que el nivel máximo de QoS solicitado al suscribirse. Por ejemplo, el nivel máximo de QoS solicitado al suscribirse es 2, pero el servidor solo admite QoS 1 y así sucesivamente.
0x01 QoS 1 concedido VOLVER -
0x02 QoS 2 concedido VOLVER -
0x04 Desconectar con Will Mensaje DESCONECTAR Solo se usa para paquetes DISCONNECT, y es adecuado para situaciones en las que el cliente quiere desconectarse normalmente pero el servidor todavía necesita publicar un mensaje de voluntad, por ejemplo, el cliente quiere enviar una notificación cuando la sesión expire.
0x10 No hay suscriptores coincidentes PUBACK, PÚBLICO Este código de motivo se utiliza para indicar al remitente que se ha recibido el mensaje, pero actualmente no hay ningún suscriptor que coincida, por lo que solo el servidor puede utilizar este código de motivo. Podemos saber que nadie recibirá nuestro mensaje al recibir un mensaje de respuesta con un código de motivo de 0x10, pero no podemos asumir que todos recibirán su mensaje al no recibir un mensaje de respuesta con un código de motivo de 0x10. la mayoría de un suscriptor. Pero debe tenerse en cuenta que usar 0x10 en lugar de 0x00 cuando no hay un suscriptor coincidente no es un comportamiento obligatorio, depende de la implementación específica del servidor.
0x11 No existía suscripción UNSUBACK Solo se usa para el mensaje UNSUBACK, que indica que no se encuentra ninguna suscripción coincidente al darse de baja.
0x18 Continuar autenticación AUTORIZACIÓN Solo se usa para el mensaje AUTH, lo que significa continuar con la autenticación. A través de este código de motivo, se puede realizar cualquier cantidad de intercambios de mensajes AUTH entre el cliente y el servidor para satisfacer las necesidades de los diferentes métodos de autenticación.
0x19 Volver a autenticar AUTORIZACIÓN Solo se usa para el mensaje AUTH. Después de que la autenticación mejorada sea exitosa, el cliente puede iniciar la reautenticación en cualquier momento enviando el mensaje AUTH con el código de motivo 0x19. Durante la reautenticación, el envío y la recepción de otros mensajes continuarán normalmente. Si la reautenticación falla, la conexión se cerrará.
0x80 Error no especificado CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DESCONECTAR Indica un error no especificado. Cuando una de las partes no desea revelar el motivo específico del error a la otra parte, o no hay un código de motivo que coincida con la situación actual en la especificación del protocolo, puede utilizar este código de motivo en el mensaje.
0x81 Paquete malformado CONECTAR, DESCONECTAR Al recibir un mensaje de control que no se puede analizar correctamente de acuerdo con la especificación del protocolo, el receptor debe enviar un mensaje DISCONNECT con un código de motivo de 0x81 para desconectarse. Si hay un problema con el mensaje CONNECT, el servidor debe usar el mensaje CONNACK. Cuando los bits reservados en el encabezado fijo no se establecen en 0 de acuerdo con los requisitos del protocolo, la QoS se especifica como 3, la cadena UTF-8 contiene un carácter nulo, etc. en el mensaje de control, se considerará como un mensaje con formato incorrecto. mensaje.
0x82 Error de protocolo CONECTAR, DESCONECTAR 在控制报文被按照协议规范解析后检测到的错误,比如包含协议不允许的数据,行为与协议要求不符等等,都会被认为是协议错误。接收方需要发送 Reason Code 为 0x81 的 DISCONNECT 报文来断开连接。如果是 CONNECT 报文存在问题,那么服务端应该使用 CONNACK 报文。常见的协议错误包括,客户端在一个连接内发送了两个 CONNECT 报文、一个报文中包含了多个相同的属性,以及某个属性被设置成了一个协议不允许的值等等。但是当我们有其他更具体的 Reason Code 时,就不会使用 0x81 (Malformed Packet) 或者 0x82 (Protocol Error) 了。例如,服务端已经声明自己不支持保留消息,但客户端仍然向服务端发送保留消息,这本质上也属于协议错误,但我们会选择使用 0x9A (Retain not supported) 这个能够更清楚指明错误原因的 Reason Code。
0x83 Implementation specific error CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT 报文有效,但是不被当前接收方的实现所接受。
0x84 Unsupported Protocol Version CONNACK 仅用于 CONNACK 报文。对于支持了 MQTT 5.0 的服务端来说,如果不支持客户端当前使用的 MQTT 协议版本,或者客户端指定了一个错误的协议版本或协议名。例如,客户端将协议版本设置为 6,那么服务端可以发送 Reason Code 为 0x84 的 CONNACK 报文,表示不支持该协议版本并且表明自己 MQTT 服务端的身份,然后关闭网络连接。当然服务端也可以选择直接关闭网络连接,因为使用 MQTT 3.1 或 3.1.1 的 MQTT 客户端可能并不能理解 0x84 这个 Reason Code 的含义。这两个版本都是在 CONNACK 报文使用 0x01 来表示不支持客户端指定的协议版本。
0x85 Client Identifier not valid CONNACK 仅用于 CONNACK 报文,表示 Client ID 是有效的字符串,但是服务端不允许。可能的情形有 Clean Start 为 0 但 Client ID 为空、或者 Client ID 超出了服务端允许的最大长度等等。
0x86 Bad User Name or Password CONNACK 仅用于 CONNACK 报文,表示客户端使用了错误的用户名或密码,这也意味着客户端将被拒绝连接。
0x87 Not authorized CONNACK, PUBACK, PUBREC, SUBACK, UNSUBACK, DISCONNECT 当客户端使用 Token 认证或者增强认证时,使用 0x87 来表示客户端没有被授权连接会比 0x86 更加合适。当客户端进行发布、订阅等操作时,如果没有通过服务端的授权检查,那么服务端也可以在 PUBACK 等应答报文中指定 0x87 这个 Reason Code 来指示授权结果。
0x88 Server unavailable CONNACK 仅用于 CONNACK 报文,向客户端指示当前服务端不可用。比如当前服务端认证服务异常无法接入新客户端等等。
0x89 Server busy CONNACK, DISCONNECT 向客户端指示服务端正忙,请稍后再试。
0x8A Banned CONNACK 仅用于 CONNACK 报文,表示客户端被禁止登录。例如服务端检测到客户端的异常连接行为,所以将这个客户端的 Client ID 或者 IP 地址加入到了黑名单列表中,又或者是后台管理人员手动封禁了这个客户端,当然以上这些通常需要视服务端的具体实现而定。
0x8B Server shutting down DISCONNECT 仅用于 DISCONNECT 报文,并且只有服务端可以使用。如果服务端正在或即将关闭,它可以通过主动发送 Reason Code 为 0x8B 的 DISCONNECT 报文的方式告知客户端连接因为服务端正在关闭而被终止。这可以帮助客户端避免在连接关闭后继续向此服务端发起连接请求。
0x8C Bad authentication method CONNACK, DISCONNECT 当服务端不支持客户端指定的增强认证方法,或者客户端在重新认证时使用了和之前认证不同的认证方法时,那么服务端就会发送 Reason Code 为 0x8C 的 CONNACK 或者 DISCONNECT 报文。
0x8D Keep Alive timeout DISCONNECT 仅用于 DISCONNECT 报文,并且只有服务端可以使用。如果客户端没能在 1.5 倍的 Keep Alive 时间内保持通信,服务端将会发送 Reason Code 为 0x8D 的 DISCONNECT 报文然后关闭网络连接。
0x8E Session taken over DISCONNECT 仅用于 DISCONNECT 报文,并且只有服务端可以使用。当客户端连接到服务端时,如果服务端中已经存在使用相同 Client ID 的客户端连接,那么服务端就会向原有的客户端发送 Reason Code 为 0x8E 的 DISCONNECT 报文,表示会话被新的客户端连接接管,然后关闭原有的网络连接。不管新的客户端连接中的 Clean Start 是 0 还是 1,服务端都会使用这个 Reason Code 向原有客户端指示会话被接管。
0x8F Topic Filter invalid SUBACK, UNSUBACK, DISCONNECT 主题过滤器的格式正确,但是不被服务端接受。比如主题过滤器的层级超过了服务端允许的最大数量限制,或者主题过滤器中包含了空格等不被当前服务端接受的字符。
0x90 Topic Name invalid CONNACK, PUBACK, PUBREC, DISCONNECT 主题名的格式正确,但是不被客户端或服务端接受。
0x91 Packet Identifier in use PUBACK, PUBREC, SUBACK, UNSUBACK 表示收到报文中的 Packet ID 正在被使用,例如发送方发送了一个 Packet ID 为 100 的 QoS 1 消息,但是接收方认为当前有一个使用相同 Packet ID 的 QoS 2 消息还没有按成它的报文流程。这通常意味着当前客户端和服务端之前的会话状态不匹配,可能需要通过设置 Clean Start 为 1 重新连接来重置会话状态。
0x92 Packet Identifier not found PUBREL, PUBCOMP 表示未找到对应的 Packet ID,这只会在 QoS 2 的报文交互流程中发生。比如当接收方回复 PUBREC 报文时,发送方未找到使用相同 Packet ID 的等待确认的 PUBLISH 报文,或者当发送方发送 PUBREL 报文时,接收方未找到使用相同 Packet ID 的 PUBREC 报文。这通常意味着当前客户端和服务端之间的会话状态不匹配,可能需要通过设置 Clean Start 为 1 重新连接来重置会话状态。
0x93 Receive Maximum exceeded DISCONNECT 仅用于 DISCONNECT 报文,表示超出了接收最大值。MQTT 5.0 增加了流控机制,客户端和服务端在连接时通过 Receive Maximum 属性约定它们愿意并发处理的可靠消息数(QoS > 0)。所以一旦发送方发送的没有完成确认的消息超过了这一数量限制,接收方就会发送 Reason Code 为 0x93 的 DISCONNECT 报文然后关闭网络连接。
0x94 Topic Alias invalid DISCONNECT 仅用于 DISCONNECT 报文,表示主题别名不合法。如果 PUBLISH 报文中的主题别名值为 0 或者大于连接时约定的最大主题别名,接收方会将此视为协议错误,它将发送 Reason Code 为 0x94 的 DISCONNECT 报文然后关闭网络连接。
0x95 Packet too large CONNACK, DISCONNECT 用于表示报文超过了最大允许长度。客户端和服务端各自允许的最大报文长度,可以在 CONNECT 和 CONNACK 报文中通过 Maximum Packet Size 属性约定。当一方发送了过大的报文,那么另一方将发送 Reason Code 为 0x95 的 DISCONNECT 报文,然后关闭网络连接。由于客户端可以在连接时设置遗嘱消息,因此 CONNECT 报文也有可能超过服务端能够处理的最大报文长度限制,此时服务端需要在 CONNACK 报文中使用这个 Reason Code。
0x96 Message rate too high DISCONNECT 仅用于 DISCONNECT 报文,表示超过了允许的最大消息发布速率。需要注意它与 Quota exceeded 的区别,Message rate 限制消息的发布速率,比如每秒最高可发布多少消息,Quota 限制的是资源的配额,比如客户端每天可以发布的消息数量,但客户端可能在一小时内耗尽它的配额。
0x97 Quota exceeded CONNACK, PUBACK, PUBREC, SUBACK, DISCONNECT 用于表示超出了配额限制。服务端可能会对发布端的发送配额进行限制,比如每天最多为其转发 1000 条消息。当发布端的配额耗尽,服务端就会在 PUBACK 等确认报文中使用这个 Reason Code 提醒对方。另一方面,服务端还可能限制客户端的连接数量和订阅数量,当超出这一限制时,服务端就会通过 CONNACK 或者 SUBACK 报文向客户端指示当前超出了配额。一些严格的客户端和服务端,在发现对端超出配额时,可能会选择发送 DISCONNECT 报文然后关闭连接。
0x98 Administrative action DISCONNECT 仅用于 DISCONNECT 报文,向客户端指示连接因为管理操作而被关闭,例如运维人员在后台踢除了这个客户端连接等等。
0x99 Payload format invalid CONNACK, PUBACK, PUBREC, DISCONNECT 当消息中包含 Payload Format Indicator 属性时,接收方可以检查消息中 Payload 的格式与该属性是否匹配。如果不匹配,接收方需要发送 Reason Code 为 0x99 的确认报文。一些严格的客户端或者服务器,可能会直接发送 DISCONNECT 报文然后关闭网络连接。如果是 CONNECT 报文中的遗嘱消息存在问题,服务端将发送 Reason Code 为 0x99 的 CONNACK 报文然后关闭网络连接。
0x9A Retain not supported CONNACK, DISCONNECT 当服务端不支持保留消息,但是客户端发送了保留消息时,服务端就会向它发送 Reason Code 为 0x9A 的 DISCONNECT 报文然后关闭网络连接。由于客户端还可以在连接时将遗嘱消息设置为保留消息,所以服务端也可能在 CONNACK 报文中使用这个 Reason Code。
0x9B QoS not supported CONNACK, DISCONNECT 用于表示不支持当前的 QoS 等级。如果客户端在消息(包括遗嘱消息)中指定的 QoS 大于服务端支持的最大 QoS,服务端将会发送 Reason Code 为 0x9B 的 DISCONNECT 或者 CONNACK 报文然后关闭网络连接。在大部份情况下,这个 Reason Code 都是由服务端使用。但是在客户端收到不是来自订阅的消息,并且消息的 QoS 大于它支持的最大 QoS 时,它也会发送 Reason Code 为 0x9B 的 DISCONNECT 报文然后关闭网络连接。这种情况通常意味着服务端的实现可能存在问题。
0x9C Use another server CONNACK, DISCONNECT 服务端在 CONNACK 或者 DISCONNECT 报文中通过这个 Reason Code 告知客户端应该临时切换到另一个服务端。如果另一个服务端不是客户端已知的,那么这个 Reason Code 还需要配合 Server Reference 属性一起使用,以告知客户端新的服务端的地址。
0x9D Server moved CONNACK, DISCONNECT 服务端在 CONNACK 或者 DISCONNECT 报文中通过这个 Reason Code 告知客户端应该永久切换到另一个服务端。如果另一个服务端不是客户端已知的,那么这个 Reason Code 还需要配合 Server Reference 属性一起使用,以告知客户端新的服务端的地址。
0x9E Shared Subscriptions not supported SUBACK, DISCONNECT 当服务端不支持共享订阅,但是客户端尝试建立共享订阅时,服务端可以发送 Reason Code 为 0x9E 的 SUBACK 报文拒绝这次订阅请求,也可以直接发送 Reason Code 为 0x9E 的 DISCONNECT 报文然后关闭网络连接。
0x9F Connection rate exceeded CONNACK, DISCONNECT 用于表示客户端已超过连接速率限制。服务端可以对客户端的连接速率做出限制,客户端连接过快时,服务端可以发送 Reason Code 为 0x9F 的 CONNACK 报文来拒绝新的连接。当然这并不是绝对的情况,考虑到不是所有的客户端都会等待一段时间再重新发起连接,一些服务端实现可能会选择暂时挂起连接而不是返回 CONNACK。
0xA0 Maximum connect time DISCONNECT Solo se usa para paquetes DISCONNECT, y solo el servidor puede usarlo. Por razones de seguridad, el servidor puede limitar el tiempo máximo de conexión del cliente en una sola autorización, por ejemplo, al usar la autenticación JWT, la conexión del cliente no debe continuar después de que caduque el JWT. En este caso, el servidor puede enviar un mensaje DISCONNECT con Reason Code 0xA0 para indicarle al cliente que la conexión está cerrada porque se ha excedido el tiempo máximo de conexión autorizado. Después de recibir el mensaje DISCONNECT que contiene el código de motivo, el cliente puede volver a obtener las credenciales de autenticación y solicitar la conexión nuevamente.
0xA1 No se admiten los identificadores de suscripción RETROCEDER, DESCONECTAR Cuando el servidor no admite el identificador de suscripción, pero la solicitud de suscripción del cliente contiene el identificador de suscripción, el servidor puede enviar un paquete SUBACK con un código de motivo de 0xA1 para rechazar la solicitud de suscripción, o enviar directamente una DESCONEXIÓN con un código de motivo de 0xA1 El paquete luego cierra la conexión de red.
0xA2 No se admiten suscripciones comodín RETROCEDER, DESCONECTAR Cuando el servidor no admite la suscripción con comodines, pero la solicitud de suscripción del cliente contiene comodines de temas, el servidor puede enviar un mensaje SUBACK con un código de motivo 0xA2 para rechazar la solicitud de suscripción, o enviar directamente un mensaje DISCONNECT con un código de motivo 0xA2. cerrar la conexión de red.

Declaración de derechos de autor: este artículo es original de EMQ, indique la fuente para la reimpresión.

Enlace original: https://www.emqx.com/zh/blog/mqtt5-new-features-reason-code-and-ack

Supongo que te gusta

Origin blog.csdn.net/emqx_broker/article/details/131982894
Recomendado
Clasificación