Os pacotes de controle MQTT são os 15 tipos de mensagem que clientes e brokers trocam, do CONNECT ao AUTH, e toda interação MQTT é construída a partir deles. Esta referência explica o que cada pacote faz, quem o envia, como reconhecê-lo pelo primeiro byte e como ele aparece nos logs de depuração do cliente, para que você consiga acompanhar uma conversa com um broker e identificar exatamente onde ela dá errado.
Pacotes de Controle MQTT em Resumo
O tipo do pacote fica nos quatro bits mais altos do primeiro byte de cada pacote. O MQTT 3.1.1 define os tipos 1 a 14; o MQTT 5 adiciona o tipo 15, AUTH. O tipo 0 é reservado e nunca é válido.
| Tipo | Nome | Direção | Primeiro byte | Finalidade |
|---|---|---|---|---|
| 1 | CONNECT | Cliente para broker | 0x10 | Abrir uma sessão |
| 2 | CONNACK | Broker para cliente | 0x20 | Aceitar ou recusar a conexão |
| 3 | PUBLISH | Ambos | 0x30-0x3F | Entregar uma mensagem da aplicação |
| 4 | PUBACK | Ambos | 0x40 | Confirmar um publish QoS 1 |
| 5 | PUBREC | Ambos | 0x50 | QoS 2 etapa 1: publish recebido |
| 6 | PUBREL | Ambos | 0x62 | QoS 2 etapa 2: liberação |
| 7 | PUBCOMP | Ambos | 0x70 | QoS 2 etapa 3: concluído |
| 8 | SUBSCRIBE | Cliente para broker | 0x82 | Solicitar assinaturas |
| 9 | SUBACK | Broker para cliente | 0x90 | Conceder ou recusar assinaturas |
| 10 | UNSUBSCRIBE | Cliente para broker | 0xA2 | Remover assinaturas |
| 11 | UNSUBACK | Broker para cliente | 0xB0 | Confirmar o cancelamento da assinatura |
| 12 | PINGREQ | Cliente para broker | 0xC0 | Sonda de keep alive |
| 13 | PINGRESP | Broker para cliente | 0xD0 | Resposta de keep alive |
| 14 | DISCONNECT | Cliente para broker (ambos no MQTT 5) | 0xE0 | Encerrar a conexão de forma limpa |
| 15 | AUTH | Ambos (somente MQTT 5) | 0xF0 | Troca de autenticação estendida |
Conhecer o primeiro byte ajuda quando você lê um hex dump bruto: 0xC0 0x00 é um PINGREQ, 0x82 inicia um SUBSCRIBE. O layout em nível de byte dos cabeçalhos e payloads é abordado no guia sobre a estrutura de pacotes MQTT.
Observando Pacotes de Controle em um Log de Depuração
A forma mais fácil de ver esses pacotes é a flag -d dos clientes Mosquitto. Usando o servidor MQTT público, que serve apenas para testes:
mosquitto_sub -h broker.connectmq.com -p 1883 -i pkt-demo-e41f \
-t "connectmq/demo/e41f/#" -q 1 -k 10 -d
Em um segundo terminal, publique uma mensagem:
mosquitto_pub -h broker.connectmq.com -p 1883 -i pkt-pub-e41f \
-t "connectmq/demo/e41f/temp" -m "22.1" -q 1 -d
A saída do assinante será parecida com esta:
Client pkt-demo-e41f sending CONNECT
Client pkt-demo-e41f received CONNACK (0)
Client pkt-demo-e41f sending SUBSCRIBE (Mid: 1, Topic: connectmq/demo/e41f/#, QoS: 1, Options: 0x00)
Client pkt-demo-e41f received SUBACK
Subscribed (mid: 1): 1
Client pkt-demo-e41f received PUBLISH (d0, q1, r0, m1, 'connectmq/demo/e41f/temp', ... (4 bytes))
Client pkt-demo-e41f sending PUBACK (m1, rc0)
22.1
Client pkt-demo-e41f sending PINGREQ
Client pkt-demo-e41f received PINGRESP
O keep alive -k 10 faz o PINGREQ aparecer depois de dez segundos ociosos. Na linha do PUBLISH, d0, q1, r0, m1 significa DUP 0, QoS 1, retain 0 e message ID 1. O Paho Python imprime linhas semelhantes com client.enable_logger(), e o MQTT.js faz o mesmo com a variável de ambiente DEBUG=mqttjs*.
Pacotes de Conexão: CONNECT, CONNACK, DISCONNECT
CONNECT é sempre o primeiro pacote que um cliente envia. Ele carrega a versão do protocolo, a flag clean session ou clean start, o keep alive, o client ID, um Last Will opcional e usuário e senha opcionais. No MQTT 5 ele também carrega properties como Session Expiry Interval, Receive Maximum e Topic Alias Maximum. Enviar um segundo CONNECT na mesma conexão é um erro de protocolo.
CONNACK é a resposta do broker. Ele contém a flag Session Present e um código de retorno (3.1.1) ou reason code (MQTT 5). Brokers MQTT 5 também usam properties do CONNACK para informar seus limites ao cliente: Maximum QoS, Maximum Packet Size, Topic Alias Maximum, se retain, wildcards ou shared subscriptions estão disponíveis e um client ID atribuído caso o cliente tenha enviado um vazio. Quando uma conexão falha, o CONNACK é o primeiro lugar a olhar; veja códigos de retorno do CONNACK MQTT.
DISCONNECT encerra a conexão de forma limpa. Um cliente que envia DISCONNECT antes de fechar o socket suprime a sua mensagem de Last Will (exceto no MQTT 5 com o reason code 0x04). No MQTT 3.1.1 só o cliente envia DISCONNECT; no MQTT 5 o broker também pode enviar um, com um reason code que explica o motivo, como 0x8E Session taken over ou 0x97 Quota exceeded. Se você observar um loop de reconexão, procure DISCONNECTs enviados pelo broker; o guia sobre por que um cliente MQTT fica desconectando percorre as causas.
Pacotes de Publicação: PUBLISH e as Confirmações
PUBLISH carrega a mensagem da aplicação em qualquer direção: do cliente para o broker quando você publica e do broker para o cliente quando você recebe. As flags do fixed header guardam DUP, QoS e RETAIN.
As confirmações dependem do QoS, explicado em detalhes em níveis de QoS MQTT:
| QoS | Fluxo de pacotes | Total de pacotes por mensagem |
|---|---|---|
| 0 | PUBLISH | 1 |
| 1 | PUBLISH, PUBACK | 2 |
| 2 | PUBLISH, PUBREC, PUBREL, PUBCOMP | 4 |
- PUBACK confirma uma mensagem QoS 1. Até ele chegar, o remetente guarda a mensagem e pode reenviá-la com DUP ativado depois de reconectar.
- PUBREC é o "recebi" do destinatário no QoS 2. A partir daí, o remetente pode descartar o payload da mensagem.
- PUBREL avisa o destinatário que ele pode liberar a mensagem para os assinantes e que o packet ID poderá ser reutilizado em breve.
- PUBCOMP encerra a troca QoS 2.
Observe que cada salto é independente. Um publish QoS 1 de um sensor para o broker e uma entrega QoS 2 do broker para um assinante são trocas separadas. No MQTT 5 essas confirmações carregam reason codes, então um PUBACK pode dizer 0x10 No matching subscribers ou 0x87 Not authorized.
Pacotes de Assinatura: SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK
SUBSCRIBE contém um packet identifier e um ou mais filtros de topic, cada um com um QoS solicitado. O MQTT 5 adiciona opções de assinatura como No Local, Retain As Published e Retain Handling, além de um Subscription Identifier opcional.
SUBACK devolve um código por filtro, na mesma ordem. Leia cada entrada: um único SUBSCRIBE com três filtros pode ter sucesso em dois e falhar em um. No 3.1.1 o valor de falha é 0x80; o MQTT 5 informa motivos específicos, como 0x8F Topic Filter invalid ou 0x9E Shared Subscriptions not supported.
UNSUBSCRIBE e UNSUBACK fazem o mesmo para a remoção. O MQTT 5 adiciona reason codes por filtro ao UNSUBACK, incluindo 0x11 No subscription existed.
Pacotes de Keep Alive: PINGREQ e PINGRESP
PINGREQ e PINGRESP são pacotes de dois bytes que provam que a conexão está viva quando não há outro tráfego. O cliente envia PINGREQ se não tiver enviado nada dentro do intervalo de keep alive; o broker precisa responder com PINGRESP. Se o broker não receber nada por 1,5 vez o keep alive, ele fecha a conexão. Se o cliente não receber o PINGRESP em um tempo razoável, deve considerar a conexão morta. O guia sobre o intervalo de keep alive MQTT explica como escolher o valor.
AUTH: A Novidade do MQTT 5
AUTH oferece suporte à autenticação estendida, como mecanismos de desafio-resposta, por meio das properties Authentication Method e Authentication Data. É usado após o CONNECT em trocas de várias etapas e também pode iniciar uma reautenticação em uma conexão existente. A maioria das implantações, incluindo logins com usuário e senha, nunca envia AUTH, então vê-lo em uma captura é incomum, a menos que você tenha configurado um método estendido.
Checklist de Depuração por Pacote
- Nenhum CONNACK? O problema é de rede, porta ou TLS, não de MQTT.
- CONNACK com código diferente de zero? Credenciais, client ID ou versão do protocolo.
- SUBACK com 0x80 ou mais? Filtro inválido, permissão ou recurso não suportado.
- PUBLISH enviado, mas sem PUBACK? Verifique o suporte a QoS e o estado da conexão.
- PINGREQ repetido sem PINGRESP? A conexão está meio morta; reconecte.
- DISCONNECT inesperado do broker? Leia o reason code.
Veja Cada Pacote na ConnectMQ
A ConnectMQ suporta MQTT 3.1.1 e 5.0, então você pode observar tanto o fluxo clássico de pacotes quanto os reason codes e properties do MQTT 5 no mesmo broker. Para uma visão mais ampla, leia o que um broker MQTT faz com esses pacotes ou siga o tutorial de MQTT completo.
Construa com a ConnectMQ
Quando você passar dos experimentos para os dispositivos, um broker MQTT gerenciado cuida de TLS, credenciais e disponibilidade. Crie um broker Serverless gratuito em app.connectmq.com sem cartão de crédito e use o cliente no navegador e o explorador de topics ao vivo do portal enquanto depura. Você também pode comparar opções no nosso guia sobre o mercado de broker MQTT na nuvem.
Perguntas frequentes
Quantos tipos de pacotes de controle MQTT existem?
O MQTT 5 define 15 tipos de pacotes de controle, numerados de 1 a 15. O MQTT 3.1.1 tem 14, porque o pacote AUTH foi adicionado no MQTT 5.
Quais pacotes uma mensagem QoS 2 usa?
PUBLISH, PUBREC, PUBREL e PUBCOMP. O handshake de quatro etapas garante que a mensagem seja entregue exatamente uma vez entre aquele remetente e aquele destinatário.
O broker pode enviar um pacote DISCONNECT?
Somente no MQTT 5. No MQTT 3.1.1 o broker simplesmente fecha a conexão de rede; o MQTT 5 permite que ele envie antes um DISCONNECT com um reason code.
Por que vejo PINGREQ nos meus logs?
O PINGREQ é a sonda de keep alive do cliente, enviada quando ele fica ocioso durante o intervalo de keep alive. Pares regulares de PINGREQ e PINGRESP são normais e mostram que a conexão está saudável.



