O modo de assinatura MQTT dinâmica do Node-RED permite que um fluxo decida quais topics escutar enquanto está rodando, em vez de fixar um único topic no node mqtt in. Neste tutorial você vai configurar um assinante dinâmico, adicionar e remover topics com msg.action, listar as assinaturas ativas, restaurá-las depois de um restart e controlar tudo a partir de uma lista simples de dispositivos.
Quando você precisa de assinaturas dinâmicas
Um node mqtt in comum assina um filtro de topic fixo no momento do deploy. Isso atende à maioria dos fluxos, principalmente quando um wildcard como site/+/telemetry já cobre todos os dispositivos. As assinaturas dinâmicas compensam a ligação extra quando:
- Um operador de uma planta em Campinas escolhe em um dashboard qual máquina acompanhar, e você quer que apenas os dados daquela máquina trafeguem.
- A lista de dispositivos fica em um banco de dados ou em um topic de configuração e muda sem redeploy.
- Um wildcard traria muito mais tráfego do que o necessário, por exemplo
#em um site movimentado. - Você quer seguir temporariamente um topic de debug durante uma investigação e depois descartá-lo.
- Você está perto do limite de assinaturas de um broker e precisa ser seletivo.
O último ponto importa em infraestrutura compartilhada. O servidor MQTT público (gratuito) em broker.connectmq.com, por exemplo, permite 10 assinaturas por cliente, então assinar sob demanda é uma forma prática de ficar dentro do limite. Lembre-se de que ele serve apenas para testes e protótipos, não para dados de produção.
Configure o node mqtt in no modo dinâmico
As assinaturas dinâmicas chegaram no Node-RED 2.2 e fazem parte de todas as versões atuais. Para habilitá-las:
- Arraste um node
mqtt inpara o canvas e abra-o. - Selecione ou crie um node de configuração de broker. Para testes, use o servidor
broker.connectmq.com, a porta1883e um client ID exclusivo e não vazio, comonr-dyn-91c4. - Mude Action de "Subscribe to single topic" para Dynamic subscription.
- Defina Output como "auto-detect" ou "a parsed JSON object", como de costume.
- Faça o deploy.
O node agora tem uma porta de entrada, e o status mostra "connected", mas ele ainda não assina nada. Daqui em diante, tudo é controlado pelas mensagens que você envia para essa entrada.
Você também vai notar a opção Connect automatically no node de configuração do broker. Deixe-a marcada, a menos que também queira controlar a própria conexão com as ações connect e disconnect, abordadas mais adiante.
Ações de assinatura MQTT dinâmica no Node-RED
O node reage a msg.action e msg.topic:
| msg.action | msg.topic | Resultado |
|---|---|---|
subscribe |
"a/b/c" |
Assina um topic com o QoS padrão do node |
subscribe |
["a/+", "b/#"] |
Assina vários filtros de topic |
subscribe |
{ "topic": "a/b", "qos": 1 } |
Assina com opções explícitas |
unsubscribe |
"a/b/c" ou um array |
Remove essas assinaturas |
unsubscribe |
true |
Remove todas as assinaturas deste node |
getSubscriptions |
não é necessário | Envia a lista atual em msg.payload |
connect / disconnect |
não é necessário | Abre ou fecha a conexão com o broker |
A forma de objeto também aceita opções de assinatura do MQTT 5, como nl (no local), rap (retain as published) e rh (retain handling), quando o node do broker usa a versão 5 do protocolo.
As mensagens recebidas nos topics adicionados dinamicamente saem pela mesma saída de uma assinatura normal, com msg.topic definido como o topic real, então o restante do fluxo não muda.
Um exemplo funcional no servidor MQTT público
Inicie um publicador que simula três máquinas. Substitua 91c4 pela sua própria sequência aleatória para que seus topics sejam exclusivos:
for i in $(seq 1 300); do
for m in cnc1 cnc2 press1; do
mosquitto_pub -h broker.connectmq.com -p 1883 -i demo-dyn-pub-91c4 \
-t "connectmq/demo/91c4/line1/$m/telemetry" \
-m "{\"machine\":\"$m\",\"load\":$((RANDOM % 100))}"
done
sleep 3
done
Agora importe o fluxo abaixo. Ele tem nodes inject que assinam cnc1, adicionam press1, listam as assinaturas e cancelam todas.
[
{"id":"tabd","type":"tab","label":"Dynamic subscribe"},
{"id":"brkd","type":"mqtt-broker","name":"ConnectMQ public","broker":"broker.connectmq.com","port":"1883","clientid":"nr-dyn-91c4","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true},
{"id":"i1","type":"inject","z":"tabd","name":"watch cnc1","props":[{"p":"action","v":"subscribe","vt":"str"},{"p":"topic","v":"connectmq/demo/91c4/line1/cnc1/telemetry","vt":"str"}],"repeat":"","once":false,"x":130,"y":60,"wires":[["dyn"]]},
{"id":"i2","type":"inject","z":"tabd","name":"add press1 (QoS 1)","props":[{"p":"action","v":"subscribe","vt":"str"},{"p":"topic","v":"{\"topic\":\"connectmq/demo/91c4/line1/press1/telemetry\",\"qos\":1}","vt":"json"}],"repeat":"","once":false,"x":150,"y":110,"wires":[["dyn"]]},
{"id":"i3","type":"inject","z":"tabd","name":"list","props":[{"p":"action","v":"getSubscriptions","vt":"str"}],"repeat":"","once":false,"x":110,"y":160,"wires":[["dyn"]]},
{"id":"i4","type":"inject","z":"tabd","name":"unsubscribe all","props":[{"p":"action","v":"unsubscribe","vt":"str"},{"p":"topic","v":"true","vt":"bool"}],"repeat":"","once":false,"x":140,"y":210,"wires":[["dyn"]]},
{"id":"dyn","type":"mqtt in","z":"tabd","name":"dynamic","topic":"","qos":"0","datatype":"auto-detect","broker":"brkd","inputs":1,"x":380,"y":130,"wires":[["dbgd"]]},
{"id":"dbgd","type":"debug","z":"tabd","name":"received","active":true,"complete":"true","x":560,"y":130,"wires":[]}
]
Clique em "watch cnc1" e apenas os dados de cnc1 aparecem na barra lateral de debug. Clique em "add press1" e as duas máquinas aparecem. "list" mostra as assinaturas ativas, e "unsubscribe all" interrompe o fluxo de dados sem redeploy.
Restaure as assinaturas depois de um restart
Esta é a parte que a maioria esquece: as assinaturas dinâmicas vivem na memória. Quando você reimplanta o node, reinicia o Node-RED ou a conexão com o broker cai e reconecta com uma sessão limpa, o node pode voltar sem nenhuma assinatura. Planeje isso desde o início.
Um padrão confiável é guardar a lista desejada em um contexto persistente e reaplicá-la na inicialização:
// Function node "apply subscriptions"
// Entrada: msg.payload = array de IDs de máquinas, ex.: ["cnc1", "press1"]
const prefix = "connectmq/demo/91c4/line1/";
const wanted = Array.isArray(msg.payload) ? msg.payload : [];
global.set("watchedMachines", wanted, "file"); // requer um context store em arquivo
// Duas mensagens, em ordem, por uma única saída
return [[
{ action: "unsubscribe", topic: true },
{ action: "subscribe", topic: wanted.map(m => ({ topic: prefix + m + "/telemetry", qos: 1 })) }
]];
Os colchetes duplos enviam as duas mensagens em sequência pela única saída, então o unsubscribe sempre chega antes do novo subscribe. Depois, adicione um node inject configurado para disparar uma vez após alguns segundos, com o payload definido como a propriedade global #:(file)::watchedMachines (a sintaxe que o Node-RED usa para ler de um context store nomeado), e ligue-o à mesma função. A configuração do armazenamento em arquivo está explicada no nosso guia sobre contexto no Node-RED.
Limpar tudo antes de reassinar mantém o estado do node previsível: o que você guardou é exatamente o que você recebe.
Controlando assinaturas por um dashboard ou topic de configuração
Como a entrada é apenas uma mensagem, qualquer coisa pode controlá-la:
- Dropdown no dashboard. Um dropdown do Dashboard 2.0 envia a máquina selecionada; um node Change monta
msg.action = "subscribe"e o topic. Envie antes um unsubscribe para a seleção anterior. - Topic de configuração. Publique uma lista JSON retida de máquinas em um topic como
connectmq/demo/91c4/config/watchlist. Um nodemqtt incomum a lê e alimenta a função acima, de modo que alterar a mensagem retida reconfigura todas as instâncias do Node-RED que estiverem escutando. - Endpoint HTTP. Um node
http inpode receber uma lista de outro sistema e aplicá-la da mesma forma.
O topic de configuração retido é especialmente elegante: o broker entrega a lista mais recente ao Node-RED assim que ele assina, o que também resolve o problema do restart sem armazenamento em arquivo. Se precisar limpar essa lista depois, veja nossa nota sobre como apagar retained messages.
Conexões dinâmicas com o broker
O mesmo mecanismo controla as conexões. Enviar msg.action = "disconnect" fecha a conexão com o broker e connect a reabre. Com connect, você também pode passar msg.broker contendo propriedades como broker, port, clientid, username e password para sobrescrever o node de configuração em tempo de execução. Isso é útil para alternar entre um broker de testes e o de produção, mas mantenha as credenciais fora dos fluxos: leia-as de variáveis de ambiente em um function node em vez de digitá-las em nodes inject.
Checklist de armadilhas
- Sem fio de entrada, sem assinaturas. Um node dinâmico não assina nada até receber uma mensagem.
- Client IDs duplicados. Duas instâncias do Node-RED com o mesmo client ID vão derrubar uma à outra do broker; cada instância precisa do próprio ID.
- Filtros sobrepostos. Assinar ao mesmo tempo
line1/#eline1/cnc1/telemetrypode entregar a mesma mensagem duas vezes. Mantenha os filtros disjuntos. - Limites. Respeite os limites de assinaturas e de profundidade de topic do broker; o servidor MQTT público limita os topics a 8 níveis.
- Estado perdido. Guarde a lista desejada e reaplique-a na inicialização, como mostrado acima.
- Saída errada para o topic errado. Todos os topics dinâmicos compartilham uma única saída, então roteie com um node Switch em
msg.topicse eles precisarem de tratamentos diferentes.
Se algo simplesmente não conecta, percorra o guia Node-RED MQTT não conecta antes de depurar a lógica de assinatura. Todos os detalhes das propriedades de entrada do node estão na documentação oficial dos nodes MQTT do Node-RED e no painel de ajuda integrado do node.
Use assinaturas dinâmicas com o ConnectMQ
Em um broker privado você tem espaço para crescer: o ConnectMQ é um broker MQTT gerenciado com suporte a MQTT 3.1.1 e 5.0, então as opções de assinatura do MQTT 5 na forma de objeto funcionam como esperado. O portal inclui um explorador de topics ao vivo, que facilita confirmar quais topics os dispositivos realmente publicam antes de montar uma lista de acompanhamento. Crie um broker no plano Serverless (Free) em app.connectmq.com, sem cartão de crédito, cole as credenciais no seu node de broker com TLS na porta 8883 e seu fluxo dinâmico roda sem alterações. Para entender as opções de hospedagem, leia sobre como rodar um broker MQTT na nuvem ou comece pelo tutorial de MQTT no Node-RED se esses nodes forem novidade para você.
Perguntas frequentes
Qual versão do Node-RED suporta assinaturas MQTT dinâmicas?
O Node-RED 2.2 e posteriores. Se o seu node mqtt in não tiver a opção "Dynamic subscription", atualize o Node-RED.
As assinaturas dinâmicas sobrevivem a um redeploy?
Não. Elas ficam na memória, então guarde a lista desejada em um contexto persistente ou em um topic de configuração retido e reaplique-a quando o fluxo iniciar.
Posso definir o QoS por topic com assinaturas dinâmicas?
Sim. Envie um objeto como { "topic": "a/b", "qos": 1 }, ou um array desses objetos, em msg.topic, com msg.action definido como subscribe.
Como vejo o que o node está assinando?
Envie uma mensagem com msg.action definido como getSubscriptions. O node entrega a lista atual de assinaturas em msg.payload.



