MQTT vs WebSocket ressemble à un choix entre deux protocoles concurrents, mais c'est en réalité une question de couches. WebSocket est un transport qui offre au navigateur un canal full-duplex vers un serveur ; MQTT est un protocole de messagerie qui définit les topics, les abonnements, les garanties de livraison et l'état de session, et il peut s'exécuter sur ce canal. Ce guide explique la différence, montre ce qu'une application WebSocket brute doit construire à la main et détaille la connexion d'un navigateur à un broker MQTT via WebSocket sécurisé.
Ce qu'est réellement WebSocket
WebSocket (RFC 6455) commence par une requête HTTP comportant l'en-tête Upgrade: websocket. Une fois que le serveur accepte, la connexion bascule vers un format de trames léger dans lequel chaque côté peut envoyer à tout moment des messages texte ou binaires. Il résout un problème bien précis : avant son apparition, les navigateurs ne pouvaient pas maintenir une connexion ouverte et bidirectionnelle avec un serveur.
Ce que WebSocket ne définit pas est tout aussi important. Il n'y a ni topics, ni abonnements, ni accusés de réception au-delà de TCP, ni notion de destinataire d'un message, ni comportement de reconnexion, ni état qui survive à une coupure de connexion. Chaque application construite sur un WebSocket brut invente son propre format de message et sa propre sémantique.
Ce que MQTT apporte
MQTT est un protocole applicatif doté d'un ensemble de paquets bien défini : CONNECT, PUBLISH, SUBSCRIBE, accusés de réception, etc. Il vous offre :
- Un routage par topic via un broker, avec les jokers
+et#. - Des garanties de livraison QoS 0, 1 et 2 pour chaque message.
- Des retained messages, pour qu'un nouveau client reçoive immédiatement la dernière valeur connue.
- Des sessions persistantes qui mettent les messages en file d'attente pendant qu'un client est hors ligne.
- Le keep alive et le Last Will pour détecter la présence en ligne ou hors ligne.
- Les nouveautés de MQTT 5, comme l'expiration des messages, les response topics pour le modèle requête/réponse, les user properties et les reason codes.
MQTT fonctionne normalement sur TCP simple ou TLS, mais la spécification définit aussi comment le transporter sur WebSocket, avec le sous-protocole mqtt. C'est ce qui permet à un navigateur de parler le même protocole qu'un ESP32. Pour comprendre comment le broker achemine tout cela, consultez le fonctionnement de MQTT.
Tableau comparatif MQTT vs WebSocket
| Aspect | WebSocket brut | MQTT (sur TCP ou WebSocket) |
|---|---|---|
| Couche | Transport (trames, full-duplex) | Protocole de messagerie applicatif |
| Format des messages | Celui que vous définissez | Paquets standard avec topics et propriétés |
| Routage | Décidé par votre code serveur | Le broker route par topic et joker |
| Diffusion vers de nombreux clients | Vous suivez les connexions et bouclez | Le broker livre à tous les abonnés correspondants |
| Garanties de livraison | Aucune au-delà de TCP | QoS 0, 1, 2 |
| Dernier état connu | Vous construisez un cache | Retained messages |
| Mise en tampon hors ligne | Vous la construisez | Sessions persistantes |
| Présence | Vous construisez des heartbeats | Keep alive et Last Will |
| Prise en charge des appareils | Surtout navigateurs et serveurs | Microcontrôleurs, passerelles, serveurs, navigateurs |
| Interopérabilité | Uniquement avec votre propre serveur | N'importe quel client et broker MQTT |
Ce qu'une application WebSocket brute doit construire
Voici une image réaliste du backend d'un tableau de bord en WebSocket brut. Le serveur conserve une table des navigateurs connectés. Les appareils envoient leurs mesures via HTTP ou leur propre socket. Lorsqu'une mesure arrive, le serveur décide qui doit la recevoir, parcourt les sockets concernés et envoie du JSON. Puis les exigences arrivent :
- Les navigateurs ne doivent recevoir que les données des sites qu'ils consultent : vous ajoutez donc un type de message « subscribe » et un mécanisme de filtrage.
- Un tableau de bord fraîchement ouvert doit afficher immédiatement les valeurs actuelles : vous ajoutez un cache des dernières valeurs.
- Les clients mobiles décrochent souvent : vous ajoutez des heartbeats et une logique de reconnexion dans le navigateur.
- Les commandes doivent être confirmées : vous ajoutez des identifiants de message et des accusés de réception.
- Il vous faut un second serveur pour absorber la charge : vous ajoutez une couche pub/sub entre serveurs pour qu'une mesure reçue par l'un atteigne les navigateurs connectés à l'autre.
À ce stade, vous avez reconstruit un broker, sans l'interopérabilité. Avec MQTT sur WebSocket, chacune de ces fonctionnalités existe déjà, et appareils comme navigateurs partagent un seul système.
Le WebSocket brut reste le bon choix pour certains usages : une fonction de chat dans une application web existante, l'édition collaborative, un serveur de jeu, ou tout cas où les deux extrémités sont votre propre code et où la sémantique des messages est propre à votre application.
Connecter un navigateur à MQTT via WebSocket
ConnectMQ expose MQTT sur WebSocket sur le port 8083 et sur WebSocket sécurisé sur le port 8084, tous deux sur le chemin /mqtt. Les navigateurs servis en HTTPS doivent utiliser la variante sécurisée. L'exemple ci-dessous utilise MQTT.js depuis un CDN et le serveur MQTT public gratuit, réservé aux tests et aux prototypes : vous pouvez l'enregistrer dans un fichier HTML et l'ouvrir directement.
// Chargez d'abord MQTT.js, par exemple :
// <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 });
// Publie une mesure retained pour que les retardataires la voient immédiatement
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}'`);
Exécutez la commande mosquitto_pub affichée depuis un terminal : la console du navigateur montre le message arrivant d'un client TCP classique. C'est tout l'intérêt de MQTT sur WebSocket : le transport diffère, mais les topics et la sémantique restent les mêmes.
Pour un broker privé, remplacez l'hôte de l'URL par l'adresse de votre broker et ajoutez username: "YOUR_USERNAME" et password: "YOUR_PASSWORD" aux options, avec clientId: "YOUR_CLIENT_ID". N'oubliez pas que tout ce qui est envoyé au navigateur est visible par son utilisateur : attribuez aux clients navigateur leurs propres identifiants limités plutôt que de réutiliser ceux des appareils ou du backend. Le guide MQTT sur WebSocket approfondit les ports, les proxys et le dépannage, et MQTT dans le navigateur avec JavaScript construit un tableau de bord complet.
Performances et surcoût
MQTT sur WebSocket ajoute un petit en-tête de trame WebSocket à chaque paquet MQTT, plus la mise à niveau HTTP initiale. Pour le trafic d'un tableau de bord, ce coût est négligeable. Pour les appareils contraints, il n'y a aucune raison d'utiliser WebSocket : connectez-vous en TCP sur 1883 ou en TLS sur 8883 et économisez les octets. Une répartition courante consiste à placer les appareils sur 8883 et les navigateurs sur 8084, tous parlant au même broker.
Pièges courants
- Mauvais chemin. De nombreux brokers, dont ConnectMQ, attendent
/mqtt. Une connexion au chemin racine échoue avec une erreur de handshake. - Contenu mixte. Une page servie en HTTPS ne peut pas ouvrir de connexion
ws://. Utilisezwss://et le port 8084. - Client IDs partagés. Deux onglets de navigateur avec le même client ID codé en dur vont s'éjecter mutuellement en boucle. Générez-en un par onglet.
- Proxys d'entreprise. Certains proxys perturbent les mises à niveau WebSocket sur des ports non standard. Testez depuis les réseaux qu'utilisent réellement vos utilisateurs.
- Fuite de secrets. N'intégrez jamais d'identifiants de backend ou d'appareil dans le code front-end.
Lequel choisir ?
Si vous développez une fonction temps réel dont les deux extrémités sont votre propre code web et dont la sémantique est unique, le WebSocket brut convient. Si des navigateurs doivent voir des données d'appareils, si plusieurs clients partagent les mêmes données, ou si vous avez besoin de garanties, d'état retained et de présence, choisissez MQTT et utilisez WebSocket comme transport dans le navigateur. Un broker MQTT managé vous fournit les deux points d'accès, TCP pour les appareils et WSS pour les navigateurs, sans avoir à gérer l'infrastructure vous-même. Pour une introduction complète au protocole, commencez par le tutoriel MQTT.
Créez des tableaux de bord temps réel sur ConnectMQ
ConnectMQ sert MQTT sur 1883 et 8883 et MQTT sur WebSocket sur 8083 et 8084 avec un certificat Let's Encrypt, afin que appareils et navigateurs se connectent au même broker. Créez un broker Serverless gratuit sur app.connectmq.com, sans carte bancaire, et testez-le avec le client MQTT intégré au navigateur du portail avant d'écrire la moindre ligne de code front-end.
Questions fréquentes
MQTT est-il meilleur que WebSocket ?
Ce ne sont pas des alternatives situées sur la même couche. WebSocket est un transport ; MQTT est un protocole de messagerie qui peut s'exécuter sur WebSocket. Utilisez MQTT lorsque vous avez besoin de topics, de diffusion et de garanties de livraison.
Un navigateur peut-il se connecter directement à un broker MQTT ?
Oui, si le broker prend en charge MQTT sur WebSocket. Avec ConnectMQ, utilisez wss://broker.connectmq.com:8084/mqtt et une bibliothèque comme MQTT.js.
Pourquoi ma connexion MQTT WebSocket échoue-t-elle sur une page HTTPS ?
Les navigateurs bloquent les connexions ws:// non sécurisées depuis les pages HTTPS. Passez à wss:// sur le port 8084 et vérifiez que le chemin est /mqtt.
Les appareils IoT doivent-ils utiliser MQTT sur WebSocket ?
Généralement non. Les appareils doivent utiliser MQTT directement sur TCP ou TLS, ce qui génère moins de surcoût. WebSocket sert surtout aux navigateurs et aux réseaux qui n'autorisent que le trafic web.



