MQTT vs WebSocket parece uma escolha entre dois protocolos concorrentes, mas na verdade é uma questão de camadas. O WebSocket é um transporte que dá ao navegador um canal full-duplex com um servidor; o MQTT é um protocolo de mensageria que define topics, assinaturas, garantias de entrega e estado de sessão, e pode rodar sobre esse canal. Este guia explica a diferença, mostra o que uma aplicação com WebSocket puro precisa construir à mão e percorre a conexão de um navegador a um broker MQTT sobre WebSocket seguro.
O Que o WebSocket Realmente É
O WebSocket (RFC 6455) começa como uma requisição HTTP com um header Upgrade: websocket. Quando o servidor aceita, a conexão passa a usar um formato de frames leve, em que qualquer lado pode enviar mensagens de texto ou binárias a qualquer momento. Ele resolve um problema específico: antes dele, navegadores não conseguiam manter uma conexão aberta e bidirecional com um servidor.
O que o WebSocket não define é igualmente importante. Não há topics, nem assinaturas, nem confirmações além das do TCP, nem noção de quem deve receber uma mensagem, nem comportamento de reconexão, nem estado que sobreviva a uma conexão perdida. Cada aplicação sobre um WebSocket puro inventa seu próprio formato de mensagem e sua própria semântica.
O Que o MQTT Acrescenta
O MQTT é um protocolo de aplicação com um conjunto de pacotes bem definido: CONNECT, PUBLISH, SUBSCRIBE, confirmações e assim por diante. Ele oferece:
- Roteamento baseado em topics por meio de um broker, com wildcards
+e#. - QoS 0, 1 e 2 como garantias de entrega por mensagem.
- Retained messages, para que um novo client receba imediatamente o último valor conhecido.
- Sessões persistentes, que enfileiram mensagens enquanto um client está offline.
- Keep alive e Last Will para detecção de online/offline.
- Extras do MQTT 5, como expiração de mensagens, response topics para requisição/resposta, user properties e reason codes.
O MQTT normalmente roda sobre TCP puro ou TLS, mas a especificação também define como transportá-lo sobre WebSocket, usando o subprotocolo mqtt. É isso que permite a um navegador falar o mesmo protocolo que um ESP32. Para entender como o broker roteia tudo isso, veja como o MQTT funciona.
Tabela Comparativa MQTT vs WebSocket
| Aspecto | WebSocket puro | MQTT (sobre TCP ou WebSocket) |
|---|---|---|
| Camada | Transporte (com frames, full-duplex) | Protocolo de mensageria de aplicação |
| Formato de mensagem | O que você definir | Pacotes padrão com topics e propriedades |
| Roteamento | O código do seu servidor decide | O broker roteia por topic e wildcard |
| Fan-out para muitos clients | Você rastreia conexões e percorre em loop | O broker entrega a todos os assinantes correspondentes |
| Garantias de entrega | Nenhuma além do TCP | QoS 0, 1, 2 |
| Último estado conhecido | Você constrói um cache | Retained messages |
| Buffer offline | Você constrói | Sessões persistentes |
| Presença | Você constrói heartbeats | Keep alive e Last Will |
| Suporte a dispositivos | Principalmente navegadores e servidores | Microcontroladores, gateways, servidores, navegadores |
| Interoperabilidade | Apenas com o seu próprio servidor | Qualquer client e broker MQTT |
O Que uma Aplicação com WebSocket Puro Precisa Construir
Veja um retrato realista do backend de um dashboard com WebSocket puro. O servidor mantém um mapa dos navegadores conectados. Os dispositivos enviam leituras via HTTP ou por seu próprio socket. Quando uma leitura chega, o servidor decide quem deve recebê-la, percorre os sockets correspondentes e envia JSON. Então chegam os requisitos:
- Os navegadores só devem receber dados das plantas que estão visualizando (por exemplo, a unidade de Joinville, e não a de Manaus), então você adiciona um tipo de mensagem "subscribe" e um esquema de filtragem.
- Um dashboard recém-aberto deve mostrar os valores atuais imediatamente, então você adiciona um cache de últimos valores.
- Clients móveis caem com frequência, então você adiciona heartbeats e lógica de reconexão no navegador.
- Comandos precisam de confirmação, então você adiciona IDs de mensagem e acknowledgments.
- Você precisa de um segundo servidor por causa da carga, então adiciona uma camada de pub/sub entre os servidores para que uma leitura recebida em um chegue aos navegadores conectados no outro.
Nesse ponto, você reconstruiu um broker, mas sem a interoperabilidade. Com MQTT sobre WebSocket, cada um desses recursos já existe, e dispositivos e navegadores compartilham um único sistema.
O WebSocket puro ainda é a escolha certa para alguns trabalhos: um chat dentro de uma aplicação web existente, edição colaborativa, um servidor de jogos ou qualquer caso em que as duas pontas sejam código seu e a semântica das mensagens seja exclusiva da sua aplicação.
Conecte um Navegador ao MQTT sobre WebSocket
O ConnectMQ expõe MQTT sobre WebSocket na porta 8083 e sobre WebSocket seguro na porta 8084, ambos no caminho /mqtt. Navegadores que carregam páginas via HTTPS precisam usar a variante segura. O exemplo abaixo usa o MQTT.js a partir de uma CDN e o servidor MQTT público (gratuito), então você pode salvá-lo como um arquivo HTML e abri-lo diretamente. O servidor MQTT público serve apenas para testes e protótipos, nunca para dados de produção.
// Carregue o MQTT.js primeiro, por exemplo:
// <script src="https://unpkg.com/mqtt@5.10.1/dist/mqtt.min.js"></script>
const prefix = "connectmq/demo/" + Math.random().toString(16).slice(2, 10);
const clientId = "browser-" + Math.random().toString(16).slice(2, 10);
const client = mqtt.connect("wss://broker.connectmq.com:8084/mqtt", {
clientId,
protocolVersion: 5,
clean: true,
keepalive: 30,
reconnectPeriod: 2000,
});
client.on("connect", () => {
console.log("connected as", clientId);
client.subscribe(prefix + "/sensors/+/temperature", { qos: 1 });
// Publica uma leitura retida para que quem chegar depois a veja imediatamente
client.publish(
prefix + "/sensors/room1/temperature",
JSON.stringify({ value: 22.3, ts: Date.now() }),
{ qos: 1, retain: true }
);
});
client.on("message", (topic, payload, packet) => {
console.log(topic, payload.toString(), "retain:", packet.retain);
});
client.on("reconnect", () => console.log("reconnecting..."));
client.on("error", (err) => console.error("mqtt error:", err.message));
console.log("Publish test data with:");
console.log(`mosquitto_pub -h broker.connectmq.com -p 1883 -i cli-${clientId} -t "${prefix}/sensors/room2/temperature" -m '{"value":19.8}'`);
Rode o comando mosquitto_pub impresso em um terminal, e o console do navegador mostrará a mensagem chegando de um client TCP comum. Esse é o objetivo do MQTT sobre WebSocket: o transporte muda, os topics e a semântica são os mesmos.
Para um broker privado, troque o host da URL pelo endereço do seu broker e adicione username: "YOUR_USERNAME" e password: "YOUR_PASSWORD" às opções, com clientId: "YOUR_CLIENT_ID". Lembre-se de que tudo o que é enviado ao navegador fica visível para o usuário, então dê aos clients de navegador credenciais próprias e limitadas em vez de reutilizar credenciais de dispositivos ou do backend. O guia de MQTT sobre WebSocket aborda portas, proxies e solução de problemas em mais profundidade, e MQTT no navegador com JavaScript constrói um dashboard completo.
Desempenho e Overhead
O MQTT sobre WebSocket adiciona um pequeno header de frame WebSocket a cada pacote MQTT, além do upgrade HTTP inicial. Para o tráfego de um dashboard, esse custo é desprezível. Para dispositivos com recursos limitados, não há motivo algum para usar WebSocket; conecte-se via TCP na 1883 ou TLS na 8883 e economize os bytes. Uma divisão comum é dispositivos na 8883 e navegadores na 8084, ambos falando com o mesmo broker.
Armadilhas Comuns
- Caminho errado. Muitos brokers, incluindo o ConnectMQ, esperam
/mqtt. Conectar no caminho raiz falha com erro de handshake. - Conteúdo misto. Uma página servida via HTTPS não pode abrir uma conexão
ws://. Usewss://e a porta 8084. - Client IDs compartilhados. Duas abas do navegador com o mesmo client ID fixo no código vão se derrubar repetidamente. Gere um por aba.
- Proxies corporativos. Alguns proxies interferem em upgrades de WebSocket em portas não padrão. Teste a partir das redes que seus usuários realmente usam.
- Vazamento de segredos. Nunca embuta credenciais de backend ou de dispositivos no código de front-end.
Qual Você Deve Escolher?
Se você está construindo um recurso em tempo real em que as duas pontas são seu próprio código web e a semântica é única, WebSocket puro serve. Se navegadores precisam ver dados de dispositivos, se vários clients compartilham os mesmos dados ou se você precisa de garantias, estado retido e presença, escolha MQTT e use WebSocket como seu transporte no navegador. Um broker MQTT gerenciado oferece os dois endpoints, TCP para dispositivos e WSS para navegadores, sem que você precise operar a infraestrutura. Para uma introdução completa ao protocolo, comece pelo tutorial de MQTT.
Crie Dashboards em Tempo Real no ConnectMQ
O ConnectMQ é um broker MQTT gerenciado que serve MQTT nas portas 1883 e 8883 e MQTT sobre WebSocket nas portas 8083 e 8084, com certificado Let's Encrypt, para que dispositivos e navegadores se conectem ao mesmo broker. Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito, e teste-o com o client MQTT no navegador do portal antes de escrever uma linha sequer de código de front-end.
Perguntas frequentes
O MQTT é melhor que o WebSocket?
Eles não são alternativas na mesma camada. O WebSocket é um transporte; o MQTT é um protocolo de mensageria que pode rodar sobre WebSocket. Use MQTT quando precisar de topics, fan-out e garantias de entrega.
Um navegador pode se conectar diretamente a um broker MQTT?
Sim, se o broker suportar MQTT sobre WebSocket. Com o ConnectMQ, use wss://broker.connectmq.com:8084/mqtt e uma biblioteca como o MQTT.js.
Por que minha conexão MQTT via WebSocket falha em uma página HTTPS?
Navegadores bloqueiam conexões ws:// inseguras a partir de páginas HTTPS. Mude para wss:// na porta 8084 e verifique se o caminho é /mqtt.
Dispositivos IoT devem usar MQTT sobre WebSocket?
Normalmente não. Os dispositivos devem usar MQTT diretamente sobre TCP ou TLS, que tem menos overhead. O WebSocket serve principalmente para navegadores e redes que só permitem tráfego web.



