Fundamentos

MQTT 5 vs MQTT 3.1.1: o que mudou e vale a pena migrar?

MQTT 5 vs 3.1.1 comparados: reason codes, expiração de sessão e mensagem, user properties, assinaturas compartilhadas, topic aliases e controle de fluxo.

Atualizado · 7 min de leitura

O MQTT 3.1.1 tornou-se padrão OASIS em 2014 e, depois, padrão ISO (ISO/IEC 20922). O MQTT 5 veio em seguida, como padrão OASIS, em 2019. O modelo central — publish/subscribe sobre tópicos com três níveis de QoS — não mudou, mas o MQTT 5 adiciona os recursos para os quais as pessoas viviam criando gambiarras: relato de erros decente, expiração, metadados, assinaturas com balanceamento de carga e controle de fluxo. Veja o que realmente muda e quando isso importa.

Tabela-resumo

RecursoMQTT 3.1.1MQTT 5
Relato de erros6 códigos de CONNACK, apenas falha no SUBACKReason codes em todas as confirmações, além de reason strings
Desconexão iniciada pelo servidorO socket simplesmente fechaDISCONNECT com reason code
Duração da sessãoFlag Clean Session (liga/desliga)Clean Start + Session Expiry Interval
Expiração de mensagensNãoMessage Expiry Interval
Metadados personalizadosSó dentro do payloadUser properties
Assinaturas compartilhadasExtensões específicas de cada brokerPadrão $share/group/filter
Topic aliasesNãoSim
Request/responseApenas por convençãoResponse Topic + Correlation Data
Controle de fluxoNãoReceive Maximum, Maximum Packet Size
AutenticaçãoUsuário/senhaMais autenticação estendida via pacote AUTH

Reason codes em todo lugar

No 3.1.1, um CONNECT com falha retorna um de seis códigos, e a maioria das outras falhas é silenciosa: se uma publicação não é autorizada, o broker pode simplesmente descartá-la ou fechar a conexão. O MQTT 5 adiciona um reason code a CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, UNSUBACK, DISCONNECT e AUTH, opcionalmente com uma reason string legível. O broker também pode enviar DISCONNECT para explicar por que está fechando uma conexão, como 0x8E Session taken over. A lista completa dos códigos mais comuns está no nosso guia de erros de conexão MQTT.

Expiração de sessão e de mensagens

Session Expiry Interval

O MQTT 3.1.1 oferece um único interruptor: Clean Session. Com cleanSession=false, o broker mantém suas assinaturas e mensagens enfileiradas para sempre, o que pode se acumular para dispositivos que nunca voltam. O MQTT 5 divide isso em Clean Start (descartar uma sessão existente ao conectar?) e Session Expiry Interval (por quantos segundos manter a sessão após a desconexão). Agora um dispositivo pode dizer: mantenha minha sessão por uma hora e depois faça a limpeza.

Message Expiry Interval

Um publicador pode definir um tempo de vida em segundos para cada mensagem. Se ela não for entregue até lá — por exemplo, porque o assinante estava offline —, o broker a descarta. Isso evita que um atuador offline receba um comando obsoleto horas depois, e também vale para as mensagens retidas (retained).

User properties e metadados de conteúdo

Os pacotes do MQTT 5 podem carregar user properties: pares chave/valor UTF-8 arbitrários, parecidos com cabeçalhos HTTP. Use-as para trace IDs, versões de esquema ou identificadores de origem sem embrulhar o payload em um envelope. Duas propriedades relacionadas descrevem o próprio payload: Payload Format Indicator (binário ou UTF-8) e Content Type (por exemplo application/json).

Publicando com propriedades do MQTT 5 (MQTT.js)
client.publish('factory/line-1/temp', JSON.stringify({ c: 21.4 }), {
  qos: 1,
  properties: {
    messageExpiryInterval: 60,
    contentType: 'application/json',
    userProperties: { traceId: 'a1b2c3', schema: 'v2' },
  },
});

Assinaturas compartilhadas

Normalmente, todo assinante recebe todas as mensagens correspondentes. Uma assinatura compartilhada distribui as mensagens entre um grupo, para que você possa escalar um backend horizontalmente. Assine $share/workers/orders/# a partir de três instâncias e cada mensagem vai para apenas uma delas. Vários brokers 3.1.1 ofereciam isso como extensão proprietária; o MQTT 5 padroniza a sintaxe. Saiba mais sobre filtros em tópicos e curingas MQTT.

Topic aliases

Nomes de tópicos longos são enviados em toda publicação. Com topic aliases, um cliente mapeia um tópico para um pequeno número inteiro uma única vez e depois envia apenas o número. Cada lado anuncia quantos aliases aceita via Topic Alias Maximum. Isso economiza banda para dispositivos que publicam com frequência em tópicos longos através de links tarifados.

Request/response

O MQTT é unidirecional por design, mas muitas aplicações precisam de respostas. O MQTT 5 adiciona ao pacote de publicação um Response Topic (para onde enviar a resposta) e Correlation Data (a qual requisição a resposta pertence). Quem responde lê os dois e publica a resposta de acordo, então você não precisa mais inventar seu próprio formato de envelope.

Controle de fluxo e limites

  • Receive Maximum: quantas mensagens QoS 1 e QoS 2 não confirmadas um lado está disposto a tratar ao mesmo tempo. Isso impede que um broker rápido sobrecarregue um dispositivo lento. Veja níveis de QoS do MQTT.
  • Maximum Packet Size: cada lado pode recusar pacotes acima de um tamanho declarado.
  • Server Keep Alive: o broker pode sobrescrever o valor de keep-alive do cliente.
  • Assigned Client Identifier: se você se conecta com um client ID vazio, o broker informa o ID que gerou.

Autenticação estendida

A autenticação do MQTT 3.1.1 se limita a usuário e senha no CONNECT (além de certificados de cliente TLS no nível de transporte). O MQTT 5 adiciona o pacote AUTH e as propriedades Authentication Method e Authentication Data, permitindo esquemas de desafio/resposta como SCRAM ou Kerberos, e reautenticação em uma conexão ativa sem desconectar. O suporte varia entre brokers, então verifique antes de depender disso.

Adições menores, mas úteis

  • Opções de assinatura: No Local (não ecoar minhas próprias mensagens), Retain As Published e Retain Handling.
  • Subscription identifiers: indicam qual assinatura correspondeu a uma mensagem entregue.
  • Will Delay Interval: atrasa o Last Will para que uma reconexão rápida não o dispare.

Vale a pena migrar?

Em projetos novos, use MQTT 5 por padrão: só os erros mais claros já economizam horas de depuração. Mantenha o 3.1.1 onde o firmware ou as bibliotecas não podem ser atualizados; nada obriga uma migração, e as duas versões convivem no mesmo broker. Ao migrar, ative a versão no seu cliente (no MQTT.js, protocolVersion: 5) e verifique se o broker a aceita.

Conectar com MQTT 5 no navegador

É novo no protocolo como um todo? Comece por o que é MQTT ou experimente as duas versões agora mesmo no cliente MQTT online.

Perguntas frequentes

O MQTT 5 é retrocompatível com o MQTT 3.1.1?

Não no nível do protocolo: os formatos de pacote são diferentes e o byte de protocol level é 5 em vez de 4. Na prática, a maioria dos brokers suporta as duas versões ao mesmo tempo, então clientes MQTT 3.1.1 e MQTT 5 podem trocar mensagens pelo mesmo broker.

Devo usar MQTT 5 ou 3.1.1 em um projeto novo?

Use MQTT 5 quando tanto o seu broker quanto as suas bibliotecas cliente o suportarem, o que vale para a maioria das opções atuais. Fique no 3.1.1 em dispositivos limitados ou legados cujo firmware ou bibliotecas só implementam essa versão.

O que aconteceu com o MQTT 4?

Não existe MQTT 4. A versão 3.1.1 usa protocol level 4 no pacote CONNECT, então a versão seguinte recebeu o número 5 para coincidir com o seu protocol level e evitar confusão.