MQTT 3.1.1 vs 5.0 : c'est la question de version que toute équipe se pose dès qu'un projet dépasse le stade du prototype. Le nouveau protocole vaut-il la migration, et les anciens et nouveaux appareils peuvent-ils cohabiter ? Ce guide compare le comportement des deux versions sur le réseau et en pratique, recense les bibliothèques clientes populaires qui prennent en charge MQTT 5, et vous fournit une check-list pour faire migrer une flotte hétérogène un groupe de clients à la fois.
Un bref historique
MQTT 3.1.1 est devenu un standard OASIS en 2014 et reste la version la plus déployée. Il est compact, stable et pris en charge par pratiquement toutes les bibliothèques clientes et tous les appareils. MQTT 5.0 a suivi comme standard OASIS en 2019. Il conserve le même modèle de base (topics, niveaux de QoS, retained messages et Last Will) et ajoute les fonctionnalités que les grands déploiements construisaient jusque-là à la main : erreurs plus claires, expiration, contrôle de flux, métadonnées et répartition de charge. Il n'y a jamais eu de version 4 ; l'octet de niveau de protocole vaut 4 pour 3.1.1 et 5 pour 5.0, c'est pourquoi les bibliothèques appellent souvent 3.1.1 « protocol version 4 ».
Bonne nouvelle pour la migration : un broker peut servir les deux versions en même temps. Chaque client déclare sa version dans le paquet CONNECT, et les messages circulent entre clients 3.1.1 et 5.0 sur les mêmes topics.
MQTT 3.1.1 vs 5.0 côte à côte
| Comportement | MQTT 3.1.1 | MQTT 5.0 |
|---|---|---|
| Signalement des erreurs | Codes de retour CONNACK de 0 à 5 ; la plupart des autres échecs ferment simplement la connexion | Reason codes sur CONNACK, PUBACK, SUBACK, UNSUBACK, DISCONNECT et d'autres, plus des reason strings optionnelles |
| Durée de vie de la session | Flag clean session : pour toujours ou jamais | Clean start plus session expiry interval en secondes |
| Durée de vie des messages | Les messages attendent indéfiniment dans les sessions | Message expiry interval par message |
| Consommateurs avec répartition de charge | Non standard | Abonnements partagés avec $share/group/filter |
| Surcoût du topic | Topic complet dans chaque PUBLISH | Le topic alias remplace le topic par un entier |
| Métadonnées | Uniquement dans le payload | User properties, content type, payload format indicator |
| Requête/réponse | Simple convention | Response topic et correlation data |
| Contrôle de flux | Rien de standard | Receive maximum, maximum packet size |
| Déconnexion par le serveur | Le serveur ferme le socket silencieusement | Le serveur envoie DISCONNECT avec un reason code |
| Options d'abonnement | QoS uniquement | No local, retain as published, retain handling, subscription identifiers |
| Message Will | Envoyé immédiatement lors d'une déconnexion brutale | Will delay interval optionnel |
| Authentification | Nom d'utilisateur et mot de passe | Plus l'authentification étendue via le paquet AUTH |
| Capacités du serveur | Implicites | Le serveur peut annoncer QoS maximale, disponibilité du retain, keep alive imposé, client ID attribué |
Les changements qui comptent le plus en pratique
Reason codes. En 3.1.1, si un broker rejette une publication pour cause de quota ou de permission, le client voit souvent seulement la connexion tomber et doit deviner. En MQTT 5, le broker peut expliquer pourquoi, par exemple 0x97 (quota dépassé) ou 0x87 (non autorisé). Cela suffit à raccourcir considérablement le débogage. La référence reason codes MQTT les liste tous.
Expiration des sessions et des messages. En 3.1.1, une session persistante vit jusqu'au retour du client, ce qui peut signifier un broker conservant des messages pour des appareils retirés du service depuis des mois. MQTT 5 permet au client de dire « garde ma session 10 minutes », et aux éditeurs de dire « cette commande ne sert plus à rien après 30 secondes ». Consultez le session expiry interval MQTT pour des conseils de réglage.
Abonnements partagés. Plusieurs instances d'un service backend peuvent s'abonner à $share/workers/orders/+/new et le broker répartit les messages entre elles. Avant MQTT 5, il fallait des extensions propres à chaque broker ou une file d'attente séparée.
User properties et requête/réponse. Des métadonnées comme une version de schéma ou un identifiant de trace peuvent voyager dans les propriétés au lieu d'être emballées dans chaque payload, et les échanges requête/réponse disposent d'un response topic et de correlation data standard.
Pour un tour d'horizon fonctionnalité par fonctionnalité avec exemples, lisez les fonctionnalités de MQTT 5.
Ce qui ne change pas
La syntaxe des topics et les jokers, les trois niveaux de QoS, les retained messages, le Last Will, le keep alive, les ports et TLS fonctionnent de la même manière. Les payloads restent des octets opaques. Un abonné 3.1.1 reçoit les messages publiés par un client 5.0 ; il ne voit simplement pas les propriétés MQTT 5. C'est cette compatibilité qui rend possible une migration progressive.
Support des bibliothèques clientes
| Plateforme | Bibliothèque | Support de MQTT 5 |
|---|---|---|
| Python | paho-mqtt 2.x | Oui, passez protocol=mqtt.MQTTv5 |
| Node.js et navigateurs | MQTT.js v5 | Oui, définissez protocolVersion: 5 (4 par défaut) |
| Go | Eclipse Paho paho.mqtt.golang |
Non, 3.1.1 uniquement |
| Go | Eclipse Paho paho.golang |
Oui, MQTT 5 uniquement |
| Java | Eclipse Paho Java (paquet mqttv5), HiveMQ MQTT Client |
Oui |
| .NET | MQTTnet | Oui |
| ESP32 (ESP-IDF) | esp-mqtt | Oui, si le support MQTT 5 est activé dans la configuration de build |
| Arduino | PubSubClient, AsyncMqttClient | Non, 3.1.1 uniquement |
| CLI | mosquitto_pub et mosquitto_sub | Oui, avec -V mqttv5 |
Les versions des bibliothèques évoluent : vérifiez dans la documentation officielle avant de vous engager. La tendance à retenir : les bibliothèques côté serveur et passerelle prennent généralement en charge MQTT 5, tandis que de nombreuses bibliothèques populaires pour microcontrôleurs restent limitées à 3.1.1. C'est la principale raison pour laquelle les flottes deviennent hétérogènes.
Utiliser les fonctionnalités de MQTT 5 dans le code
Cet exemple Python se connecte en MQTT 5, demande une session de 10 minutes, publie une commande avec une expiration de 30 secondes et des user properties, et affiche les reason codes. Il s'exécute sur le serveur MQTT public gratuit, qui prend en charge les deux versions et une session expiry jusqu'à 30 minutes ; utilisez-le pour des tests, pas pour des données de production.
import time
import uuid
import paho.mqtt.client as mqtt
from paho.mqtt.packettypes import PacketTypes
from paho.mqtt.properties import Properties
PREFIX = f"connectmq/demo/{uuid.uuid4().hex[:8]}"
def on_connect(client, userdata, flags, reason_code, properties):
print("CONNACK:", reason_code, "| session present:", flags.session_present)
client.subscribe(f"{PREFIX}/cmd/#", qos=1)
def on_subscribe(client, userdata, mid, reason_code_list, properties):
print("SUBACK:", [str(rc) for rc in reason_code_list])
def on_message(client, userdata, msg):
props = msg.properties
user_props = getattr(props, "UserProperty", None)
expiry = getattr(props, "MessageExpiryInterval", None)
print(f"{msg.topic} {msg.payload.decode()} user={user_props} expiry={expiry}")
def on_publish(client, userdata, mid, reason_code, properties):
print("PUBACK:", reason_code)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=f"v5-demo-{uuid.uuid4().hex[:8]}",
protocol=mqtt.MQTTv5)
client.on_connect = on_connect
client.on_subscribe = on_subscribe
client.on_message = on_message
client.on_publish = on_publish
connect_props = Properties(PacketTypes.CONNECT)
connect_props.SessionExpiryInterval = 600 # conserver la session 10 minutes
client.connect("broker.connectmq.com", 1883, keepalive=30,
clean_start=False, properties=connect_props)
client.loop_start()
time.sleep(1)
pub_props = Properties(PacketTypes.PUBLISH)
pub_props.MessageExpiryInterval = 30
pub_props.UserProperty = [("schema", "v2"), ("source", "ops-console")]
pub_props.ContentType = "application/json"
client.publish(f"{PREFIX}/cmd/pump7", '{"action":"stop"}', qos=1,
properties=pub_props)
time.sleep(2)
client.loop_stop()
client.disconnect()
Pour constater l'interopérabilité, lancez un abonné 3.1.1 sur le même topic dans un autre terminal. Il reçoit le payload, mais pas les propriétés.
mosquitto_sub -h broker.connectmq.com -p 1883 -V mqttv311 \
-i v311-check-$RANDOM -t "connectmq/demo/+/cmd/#" -v
Check-list de migration
Utilisez cette check-list pour passer de 3.1.1 à 5.0 sans bascule brutale.
- Vérifiez le support du broker. Votre broker doit accepter les deux versions simultanément. C'est le cas de ConnectMQ : anciens et nouveaux clients peuvent partager les topics pendant la transition.
- Inventoriez les clients par bibliothèque. Listez chaque type d'appareil, passerelle et service avec sa bibliothèque MQTT et sa version. Repérez ceux qui peuvent passer à MQTT 5 dès aujourd'hui.
- Migrez d'abord les services backend. Ce sont eux qui y gagnent le plus (reason codes, abonnements partagés, contrôle de flux) et ils sont les plus faciles à redéployer.
- Remplacez la logique clean session. Faites correspondre
clean_session=Trueà un clean start avec session expiry à 0, etclean_session=Falseà un clean start à false avec une expiration explicite au lieu de « pour toujours ». - Gérez les reason codes. Journalisez reason codes et reason strings sur CONNACK, SUBACK, PUBACK et DISCONNECT, et cessez de réessayer sur les codes non réessayables comme « non autorisé ».
- Ne faites pas encore dépendre les données critiques des propriétés. Tant qu'il reste des abonnés 3.1.1, tout ce dont ils ont besoin doit rester dans le payload ou le topic.
- Introduisez l'expiration de façon réfléchie. Ajoutez d'abord l'expiration des messages aux commandes et aux alertes urgentes, là où une livraison tardive est nuisible.
- Adoptez les abonnements partagés pour les consommateurs mis à l'échelle horizontalement, et supprimez toute déduplication maison entre instances.
- Migrez les passerelles et appareils en dernier, par groupe, en surveillant l'état des connexions et les taux d'erreur après chaque vague.
- Retestez les fondamentaux. Reconnexion, Last Will, état retained et sessions persistantes doivent se comporter comme avant ; la check-list de test MQTT couvre chacun de ces points.
Faut-il migrer ?
Pour les nouveaux projets, partez sur MQTT 5 partout où vos bibliothèques le permettent. Pour les flottes existantes, migrez dès maintenant les services et les passerelles, et les appareils au gré des occasions, par exemple lors de leur prochain cycle de firmware. Il y a peu de raisons de précipiter la migration des appareils contraints dont la bibliothèque est limitée à 3.1.1, car un broker parlant les deux versions supprime toute pression. Le tutoriel MQTT couvre les fondamentaux communs si vous intégrez de nouveaux membres dans l'équipe.
Un broker MQTT managé qui prend en charge les deux versions rend la transition sans histoire. ConnectMQ accepte les clients MQTT 3.1.1 et 5.0 sur le même broker et prend en charge les fonctionnalités de MQTT 5, dont session expiry, message expiry, topic alias, response topic, retained messages et reason codes, avec les abonnements partagés sur le plan Serverless payant.
Migrez sur ConnectMQ à votre rythme
Créez un broker Serverless gratuit sur app.connectmq.com, sans carte bancaire, connectez un appareil 3.1.1 et un service MQTT 5, et vérifiez qu'ils interopèrent avant de planifier le reste de la migration.
Questions fréquentes
MQTT 3.1.1 et MQTT 5.0 sont-ils compatibles ?
Sur un même broker, oui. Les clients choisissent leur version à la connexion, et les messages circulent entre les versions. Un abonné 3.1.1 ne reçoit simplement pas les propriétés MQTT 5.
Quel est le plus grand avantage de MQTT 5 ?
Pour la plupart des équipes, ce sont les reason codes, car les échecs cessent d'être des déconnexions silencieuses. L'expiration des sessions et des messages et les abonnements partagés suivent de près.
Pourquoi MQTT 3.1.1 est-il appelé protocol version 4 ?
Le paquet CONNECT contient un octet de niveau de protocole qui vaut 4 pour MQTT 3.1.1 et 5 pour MQTT 5.0. Des bibliothèques comme MQTT.js utilisent ce nombre dans leurs options.
Dois-je passer mes appareils ESP32 à MQTT 5 ?
Pas nécessairement. Si vous utilisez une bibliothèque 3.1.1 comme PubSubClient, les appareils peuvent continuer à fonctionner avec un broker qui prend en charge les deux versions pendant que votre backend adopte MQTT 5.



