O que são tópicos MQTT?
Um tópico MQTT é uma string codificada em UTF-8 que serve como base para o roteamento de mensagens no protocolo MQTT. Assim como um caminho de URL, ele utiliza a barra / para criar uma estrutura hierárquica:
chat/sala/1
sensor/10/temperatura
sensor/+/temperatura
sensor/#
Os tópicos MQTT não precisam ser criados previamente. Um cliente MQTT os cria automaticamente ao publicar ou assinar um tópico, e também não é necessário removê-los explicitamente. Para evitar ambiguidades e facilitar a compreensão, é recomendado não iniciar ou terminar tópicos com /, como em /chat ou chat/.
No diagrama abaixo, temos um fluxo simples de publicação e assinatura MQTT. O APP 1, ao assinar o tópico sensor/2/temperatura, receberá as mensagens publicadas pelo Sensor 2 nesse mesmo tópico.
Curingas em tópicos MQTT
Os curingas MQTT incluem o curinga de nível único + e o curinga de vários níveis #. Eles são usados principalmente para que um cliente assine múltiplos tópicos de uma só vez.
Atenção: Curingas só podem ser usados em assinaturas, nunca em publicações.
Curinga de nível único (+)
O sinal de mais (+, U+002B) é um curinga que corresponde a um único nível hierárquico do tópico. Ao usá-lo, o curinga deve ocupar um nível inteiro, por exemplo:
+ Válido
sensor/+ Válido
sensor/+/temperatura Válido
sensor+ Inválido (não ocupa um nível inteiro)
Se um cliente assinar o tópico sensor/+/temperatura, ele receberá mensagens dos seguintes tópicos:
sensor/1/temperatura
sensor/2/temperatura
...
sensor/n/temperatura
No entanto, não corresponderá a estes:
sensor/temperatura
sensor/quarto/1/temperatura
Curinga de vários níveis (#)
O sinal de cerquilha (#, U+0023) é um curinga que corresponde a qualquer número de níveis em um tópico. Ele representa o nível pai e todos os seus subníveis. Ao usá-lo, o curinga deve ocupar um nível inteiro e ser o último caractere do tópico, por exemplo:
# Válido (corresponde a todos os tópicos)
sensor/# Válido
sensor/quarto# Inválido (não ocupa um nível inteiro)
sensor/#/temperatura Inválido (não é o último caractere)
Se um cliente assinar o tópico sensor/#, ele receberá mensagens dos seguintes tópicos:
sensor
sensor/temperatura
sensor/1/temperatura
Tópicos iniciados com $
Tópicos de sistema
Tópicos que começam com $SYS/ são chamados de tópicos de sistema. Eles são usados para obter informações sobre o estado do servidor MQTT, estatísticas de mensagens, eventos de conexão/desconexão de clientes, entre outros. Atualmente, o protocolo MQTT não define um padrão rígido para $SYS/, mas a maioria dos servidores MQTT segue essa convenção.
Por exemplo, o servidor EMQX permite obter o estado do cluster através dos seguintes tópicos.
Assinatura compartilhada
A assinatura compartilhada é um recurso introduzido no MQTT 5.0 para balancear a carga de assinaturas entre múltiplos assinantes. No MQTT 5.0, os tópicos de assinatura compartilhada começam com $share.
Embora o protocolo MQTT tenha introduzido a assinatura compartilhada apenas na versão 5.0, o EMQX já a suporta desde a versão 3.1.1.
No diagrama abaixo, três assinantes usam uma assinatura compartilhada para o mesmo tópico $share/g/topic. Aqui, topic é o nome real do tópico que eles estão assinando, e $share/g/ é o prefixo da assinatura compartilhada, onde g/ é o nome do grupo (pode ser qualquer string UTF-8).
Design de tópicos em diferentes cenários
Casa inteligente
Suponha que usamos sensores para monitorar temperatura, umidade e qualidade do ar no quarto, na sala e na cozinha. Podemos projetar os seguintes tópicos:
minhacasa/quarto/temperatura
minhacasa/quarto/umidade
minhacasa/quarto/qualidadedoar
minhacasa/sala/temperatura
minhacasa/sala/umidade
minhacasa/sala/qualidadedoar
minhacasa/cozinha/temperatura
minhacasa/cozinha/umidade
minhacasa/cozinha/qualidadedoar
Ao assinar minhacasa/quarto/+, recebemos dados de temperatura, umidade e qualidade do ar do quarto. Assinando minhacasa/+/temperatura, obtemos a temperatura dos três cômodos. Já minhacasa/# nos dá todos os dados.
Estações de recarga para veículos elétricos
O formato do tópico de uplink da estação é ocpp/cp/${cid}/notify/${action}, e o de downlink é ocpp/cp/${cid}/reply/${action}.
ocpp/cp/cp001/notify/bootNotification— A estação publica uma solicitação de inicialização neste tópico ao se conectar.ocpp/cp/cp001/notify/startTransaction— Publica uma solicitação de recarga aqui.ocpp/cp/cp001/reply/bootNotification— A estação deve assinar este tópico antes de se conectar para receber a resposta de inicialização.ocpp/cp/cp001/reply/startTransaction— A estação assina este tópico antes de solicitar uma recarga para receber a resposta.
Mensagens instantâneas
chat/usuario/${user_id}/inbox— Chat individual: Ao fazer login, o usuário assina este tópico de caixa de entrada para receber mensagens de amigos. Para responder, basta substituir ouser_idpelo ID do amigo.chat/grupo/${group_id}/inbox— Chat em grupo: Após entrar em um grupo, o usuário assina este tópico para receber mensagens do grupo. Para responder, publica-se diretamente neste tópico.req/usuario/${user_id}/add— Solicitação de amizade: Publica-se uma solicitação de amizade aqui (ondeuser_idé o ID do destinatário). O destinatário assina este tópico (com seu próprio ID) para receber solicitações.resp/usuario/${user_id}/add— Resposta à solicitação de amizade: Antes de adicionar um amigo, o solicitante assina este tópico (com seu próprio ID) para receber a resposta. Para responder, o destinatário publica aqui (com o ID do solicitante) indicando se aceita ou não.usuario/${user_id}/state— Status online: Os usuários podem assinar este tópico para saber o status online de seus amigos.
Perguntas frequentes sobre tópicos MQTT
Existem limites de profundidade ou comprimento para tópicos?
O protocolo MQTT especifica que o comprimento do tópico é de dois bytes, portanto, um tópico pode ter no máximo 65.535 caracteres. Recomanda-se que a profundidade do tópico não ultrapasse 7 níveis.
O servidor impõe um limite no número de tópicos?
Diferentes servidores de mensagens têm suporte variado para o número máximo de tópicos. Atualmente, a configuração padrão do EMQX não limita o número de tópicos, mas quanto mais tópicos, mais memória do servidor será consumida. Considerando que geralmente há muitos dispositivos conectados ao Broker MQTT, recomenda-se que um cliente assine no máximo 10 tópicos.
O desempenho de assinaturas com curinga é igual ao de assinaturas normais?
Assinaturas com curinga têm desempenho inferior a assinaturas normais e consomem mais recursos do servidor. O usuário deve escolher o tipo de assinatura com base em suas necessidades reais.
Um mesmo tópico pode ser usado simultaneamente com assinatura compartilhada e assinatura normal?
Sim, é possível, mas não é recomendado.
Quais são as recomendações comuns para o uso de tópicos MQTT?
- Evite usar
#para assinar todos os tópicos. - Evite iniciar ou terminar tópicos com
/, como em/chatouchat/. - Evite incluir espaços ou caracteres especiais não ASCII nos tópicos.
- Dentro de um mesmo nível hierárquico, recomenda-se o uso de sublinhado
_ou hífen-para conectar palavras (ou usar nomenclatura CamelCase).