O session expiry interval MQTT informa ao broker por quanto tempo manter a sessão de um cliente depois que ele se desconecta e, junto com a flag Clean Start, substitui a flag clean session do MQTT 3.1.1, que era do tipo tudo ou nada. Neste artigo você vai aprender como as duas configurações se combinam, como o intervalo pode ser alterado no momento da desconexão e como escolher valores sensatos para sensores, gateways e serviços de backend.
Por Que o MQTT 5 Substituiu a Flag Clean Session
No MQTT 3.1.1, o cleanSession fazia dois trabalhos com um único bit. Defini-lo como false significava "retome minha sessão antiga e mantenha esta para sempre". Não havia como dizer "retome minha sessão, mas esqueça-a se eu sumir por mais de uma hora". Os brokers contornavam isso com configurações de expiração no servidor, o que fazia o comportamento variar entre brokers e deixava sessões abandonadas se acumulando.
O MQTT 5 separa as duas preocupações:
- Clean Start (uma flag do CONNECT) responde: o broker deve descartar agora qualquer sessão existente?
- Session Expiry Interval (uma property do CONNECT, em segundos) responde: por quanto tempo a sessão deve viver depois que a conexão de rede fecha?
O design está descrito na especificação MQTT 5.0 da OASIS e é uma das melhorias mais práticas abordadas na nossa visão geral dos recursos do MQTT 5.
Como Clean Start e Session Expiry se Combinam
| Clean Start | Session Expiry Interval | Comportamento | Equivalente no 3.1.1 |
|---|---|---|---|
| true | 0 (ou ausente) | Sessão nova, excluída na desconexão | cleanSession = true |
| false | 0 (ou ausente) | Retoma a sessão existente, se houver, excluída na desconexão | Sem equivalente direto |
| true | > 0 | Descarta a sessão antiga e inicia uma nova que sobrevive à desconexão por N segundos | Sem equivalente direto |
| false | > 0 | Retoma se existir, sobrevive à desconexão por N segundos | cleanSession = false (com timeout) |
| false | 0xFFFFFFFF | Retoma se existir, nunca expira | cleanSession = false |
Alguns detalhes importam na prática:
- O timer começa quando a conexão de rede fecha, não quando o cliente publicou pela última vez.
- Se o cliente reconectar antes de o timer acabar, a sessão é retomada e o timer é cancelado.
- Quando o intervalo termina, o broker exclui as assinaturas e todas as mensagens enfileiradas.
- Se a sessão expirar, a mensagem de will é enviada no máximo nesse momento, mesmo que o will delay interval seja maior.
Alterando o Intervalo na Desconexão
O MQTT 5 permite que um cliente atualize a expiração no pacote DISCONNECT. Um dispositivo que entra em manutenção programada pode dizer "guarde minha sessão por um dia" ao sair, enquanto normalmente opera com um valor menor. Há uma restrição: se o cliente se conectou com expiração 0, não pode definir um valor diferente de zero na desconexão; o broker trata isso como erro de protocolo.
O Broker Pode Sobrescrever o Seu Valor
Um broker pode se recusar a manter sessões pelo tempo que você pede. Nesse caso ele retorna uma property Session Expiry Interval no CONNACK, e esse é o valor que vale. Sempre registre as properties do CONNACK durante o desenvolvimento para saber o número real. No broker de testes gratuito em broker.connectmq.com, o session expiry é limitado a 30 minutos.
Escolhendo um Session Expiry Interval MQTT
Pense em duas perguntas: por quanto tempo este cliente pode, realisticamente, ficar offline, e quão desatualizada uma mensagem enfileirada pode ficar antes de se tornar inútil?
| Tipo de cliente | Expiração sugerida | Justificativa |
|---|---|---|
| Dashboard ao vivo, aba do navegador | 0 | Só os dados atuais importam; as retained messages preenchem a tela na conexão |
| Sensor ligado à tomada que só publica | 0 a 300 s | Pouco estado de sessão; uma expiração curta faz a limpeza rapidamente |
| Dispositivo que recebe comandos | 1 a 24 h | Os comandos devem sobreviver a quedas de Wi-Fi e interrupções curtas |
| Dispositivo a bateria que acorda a cada hora | Um pouco mais que o intervalo de despertar | A sessão precisa durar mais que o período de sono |
| Worker de backend que processa alarmes | Horas, de acordo com o seu tempo de recuperação | Alarmes perdidos precisam ser processados depois de redeploys |
| Cliente desativado ou de teste | 0 | Evita deixar sessões órfãs para trás |
Combine intervalos de expiração longos com a property Message Expiry Interval do MQTT 5 em publicações sensíveis ao tempo. Um comando "ligar bomba" que fica seis horas em uma fila pode ser mais perigoso do que um que nunca é entregue.
Um Exemplo Prático: Sensor Sonolento com Comandos
Imagine um sensor a bateria em uma fazenda de soja que acorda a cada 15 minutos, publica uma leitura, verifica comandos de configuração e volta a dormir. Se a expiração da sessão fosse 0, qualquer comando enviado enquanto ele dormia seria descartado, porque não haveria sessão para enfileirá-lo. Se a expiração fosse infinita, um sensor que morresse em campo deixaria uma sessão acumulando comandos que ninguém vai ler. Um valor de cerca de 20 a 30 minutos cobre um despertar perdido mais alguma variação da rede, e a sessão desaparece sozinha quando o dispositivo realmente some. Envie os comandos com QoS 1 e um message expiry de algumas horas, e o dispositivo recebe tudo o que ainda for relevante na próxima conexão.
Configurando o Session Expiry no Código
Todos os exemplos usam um prefixo de demonstração único no servidor MQTT público (gratuito), que serve apenas para testes. Substitua s4e8 pela sua própria string aleatória; a área pública é visível para todos.
mosquitto_sub
# Retoma (ou cria) uma sessão que sobrevive 10 minutos após a desconexão
mosquitto_sub -h broker.connectmq.com -p 1883 -V mqttv5 \
-i expiry-demo-s4e8 -c -x 600 -q 1 -v -d \
-t 'connectmq/demo/s4e8/commands/#'
-c define Clean Start como false, e -x 600 define o Session Expiry Interval. A flag -d imprime o CONNACK, para você ver se o broker concedeu o valor.
Python (paho-mqtt 2.x)
import paho.mqtt.client as mqtt
from paho.mqtt.properties import Properties
from paho.mqtt.packettypes import PacketTypes
def on_connect(client, userdata, flags, reason_code, properties):
granted = getattr(properties, "SessionExpiryInterval", None)
print("Connected:", reason_code,
"| session present:", flags.session_present,
"| broker override:", granted)
if not flags.session_present:
client.subscribe("connectmq/demo/s4e8/commands/#", qos=1)
def on_message(client, userdata, msg):
print("Command:", msg.topic, msg.payload.decode())
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id="expiry-py-s4e8",
protocol=mqtt.MQTTv5)
client.on_connect = on_connect
client.on_message = on_message
connect_props = Properties(PacketTypes.CONNECT)
connect_props.SessionExpiryInterval = 600
client.connect("broker.connectmq.com", 1883, keepalive=60,
clean_start=False, properties=connect_props)
client.loop_start()
try:
input("Press Enter to disconnect with a 30 minute expiry...\n")
finally:
bye = Properties(PacketTypes.DISCONNECT)
bye.SessionExpiryInterval = 1800
client.disconnect(properties=bye)
client.loop_stop()
Node.js (MQTT.js v5)
const mqtt = require("mqtt");
const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
clientId: "expiry-node-s4e8",
protocolVersion: 5,
clean: false, // Clean Start = false
properties: { sessionExpiryInterval: 600 },
});
client.on("connect", (connack) => {
console.log("session present:", connack.sessionPresent,
"props:", connack.properties);
if (!connack.sessionPresent) {
client.subscribe("connectmq/demo/s4e8/commands/#", { qos: 1 });
}
});
client.on("message", (topic, payload) => {
console.log(topic, payload.toString());
});
Erros Comuns e Como Identificá-los
- Clean Start false, expiração 0. Desenvolvedores portam código 3.1.1, definem
clean: falsee esquecem a property de expiração. No MQTT 5, essa sessão é excluída no momento em que a conexão cai, então nada é enfileirado. Se as mensagens enfileiradas nunca aparecem, verifique isso primeiro. - Expiração infinita em clientes de teste. Cada script descartável com ID único e
0xFFFFFFFFdeixa uma sessão para trás. Use 0 em experimentos, a menos que esteja testando sessões. - Ignorar o Session Present. Se o broker reiniciou ou a sessão expirou, o Session Present é 0 e suas assinaturas sumiram. Sempre assine novamente nesse caso.
- Presumir durabilidade após reinícios do broker. O session expiry descreve por quanto tempo uma sessão pode viver, não é uma garantia de armazenamento. A ConnectMQ mantém o estado das sessões em memória: ele sobrevive a desconexões do cliente pelo intervalo concedido, mas é apagado se o próprio broker reiniciar.
- Trocar client IDs. A expiração está vinculada ao client ID. Um novo ID é uma nova sessão; veja boas práticas de client ID MQTT.
Como Isso se Encaixa no Panorama Geral
O session expiry é a forma do MQTT 5 de usar sessões persistentes com segurança: você tem enfileiramento offline onde precisa e limpeza automática onde não precisa. Se ainda está aprendendo as peças do protocolo, o tutorial completo de MQTT é uma boa leitura complementar.
Use Sessões MQTT 5 na ConnectMQ
A ConnectMQ é um broker MQTT gerenciado com suporte completo ao MQTT 5.0, incluindo session expiry, message expiry, topic aliases e reason codes. Você pode testar combinações de Clean Start e expiração com o cliente MQTT no navegador do portal ou com o seu próprio código e depois levar as mesmas configurações para produção. Comece no plano Serverless gratuito, sem cartão de crédito, e conecte-se com os seus YOUR_USERNAME, YOUR_PASSWORD e YOUR_CLIENT_ID gerados.
Perguntas frequentes
Qual é o session expiry interval MQTT padrão?
Se a property estiver ausente, o session expiry interval é 0, o que significa que a sessão termina quando a conexão de rede fecha. Você precisa defini-lo explicitamente para ter uma sessão persistente no MQTT 5.
Qual é a diferença entre Clean Start e clean session?
O clean session do MQTT 3.1.1 controlava tanto o descarte da sessão antiga quanto a manutenção da nova. O Clean Start do MQTT 5 controla apenas o descarte no momento da conexão, enquanto o Session Expiry Interval controla por quanto tempo a sessão vive depois.
Qual é o session expiry interval máximo?
O máximo do protocolo é 4.294.967.295 segundos (0xFFFFFFFF), o que significa que a sessão nunca expira. Os brokers podem impor limites menores e informá-los no CONNACK; o servidor MQTT público da ConnectMQ permite até 30 minutos.
Posso alterar o session expiry ao desconectar?
Sim, enviando uma property Session Expiry Interval no DISCONNECT, a menos que você tenha se conectado originalmente com expiração 0.



