Notions de base

MQTT 5 vs MQTT 3.1.1 : ce qui change et faut-il migrer ?

MQTT 5 et 3.1.1 comparés : reason codes, expiration des sessions et messages, user properties, abonnements partagés, topic aliases, requête/réponse, contrôle de flux.

Mis à jour · 7 min de lecture

MQTT 3.1.1 est devenu un standard OASIS en 2014, puis une norme ISO (ISO/IEC 20922). MQTT 5 a suivi en tant que standard OASIS en 2019. Le modèle de base — publish/subscribe sur des topics avec trois niveaux de QoS — reste inchangé, mais MQTT 5 ajoute les fonctionnalités pour lesquelles tout le monde bricolait des contournements : un vrai signalement des erreurs, l’expiration, des métadonnées, des abonnements avec répartition de charge et le contrôle de flux. Voici ce qui change réellement, et quand cela compte.

Tableau récapitulatif

FonctionnalitéMQTT 3.1.1MQTT 5
Signalement des erreurs6 codes CONNACK, échec SUBACK uniquementReason codes sur tous les acquittements, plus des reason strings
Déconnexion initiée par le serveurLe socket se ferme, c’est toutDISCONNECT avec un reason code
Durée de vie de la sessionFlag Clean Session (activé/désactivé)Clean Start + Session Expiry Interval
Expiration des messagesNonMessage Expiry Interval
Métadonnées personnaliséesUniquement dans le payloadUser properties
Abonnements partagésExtensions propres aux brokersStandard $share/group/filter
Topic aliasesNonOui
Requête/réponseSimple conventionResponse Topic + Correlation Data
Contrôle de fluxNonReceive Maximum, Maximum Packet Size
AuthentificationNom d’utilisateur/mot de passePlus l’authentification étendue via le paquet AUTH

Des reason codes partout

En 3.1.1, un CONNECT refusé renvoie l’un de six codes, et la plupart des autres échecs sont silencieux : si une publication n’est pas autorisée, le broker peut simplement l’ignorer ou fermer la connexion. MQTT 5 ajoute un reason code à CONNACK, PUBACK, PUBREC, PUBREL, PUBCOMP, SUBACK, UNSUBACK, DISCONNECT et AUTH, éventuellement accompagné d’une reason string lisible. Le broker peut aussi envoyer un DISCONNECT pour expliquer pourquoi il ferme une connexion, par exemple 0x8E Session taken over. La liste complète des codes courants se trouve dans notre guide des erreurs de connexion MQTT.

Expiration des sessions et des messages

Session Expiry Interval

MQTT 3.1.1 ne propose qu’un interrupteur : Clean Session. Avec cleanSession=false, le broker conserve vos abonnements et vos messages en file indéfiniment, ce qui peut s’accumuler pour des appareils qui ne reviennent jamais. MQTT 5 scinde cela en Clean Start (supprimer toute session existante à la connexion ?) et Session Expiry Interval (combien de secondes conserver la session après la déconnexion). Un appareil peut désormais dire : garde ma session une heure, puis fais le ménage.

Message Expiry Interval

Un éditeur peut définir une durée de vie en secondes pour chaque message. S’il n’a pas été livré d’ici là — par exemple parce que l’abonné était hors ligne — le broker le supprime. Cela évite qu’un actionneur hors ligne reçoive une commande périmée des heures plus tard, et cela s’applique aussi aux messages retenus (retained).

User properties et métadonnées de contenu

Les paquets MQTT 5 peuvent transporter des user properties : des paires clé/valeur UTF-8 arbitraires, comparables aux en-têtes HTTP. Utilisez-les pour des trace IDs, des versions de schéma ou des identifiants de source sans envelopper le payload. Deux propriétés connexes décrivent le payload lui-même : Payload Format Indicator (binaire ou UTF-8) et Content Type (par exemple application/json).

Publier avec des propriétés MQTT 5 (MQTT.js)
client.publish('factory/line-1/temp', JSON.stringify({ c: 21.4 }), {
  qos: 1,
  properties: {
    messageExpiryInterval: 60,
    contentType: 'application/json',
    userProperties: { traceId: 'a1b2c3', schema: 'v2' },
  },
});

Abonnements partagés

Normalement, chaque abonné reçoit chaque message correspondant. Un abonnement partagé répartit au contraire les messages au sein d’un groupe, ce qui permet de faire monter un backend en charge horizontalement. Abonnez trois instances à $share/workers/orders/# et chaque message n’ira qu’à l’une d’elles. Plusieurs brokers 3.1.1 proposaient cela sous forme d’extension propriétaire ; MQTT 5 en standardise la syntaxe. Pour en savoir plus sur les filtres, voir topics et jokers MQTT.

Topic aliases

Les noms de topics longs sont envoyés à chaque publication. Avec les topic aliases, un client associe une fois un topic à un petit entier, puis n’envoie plus que cet entier. Chaque partie annonce le nombre d’alias qu’elle accepte via Topic Alias Maximum. Cela économise de la bande passante pour les appareils qui publient fréquemment sur des topics longs via des liaisons facturées au volume.

Requête/réponse

MQTT est unidirectionnel par conception, mais beaucoup d’applications ont besoin de réponses. MQTT 5 ajoute au paquet de publication un Response Topic (où envoyer la réponse) et des Correlation Data (à quelle requête la réponse se rapporte). Le répondeur lit les deux et publie sa réponse en conséquence : plus besoin d’inventer votre propre format d’enveloppe.

Contrôle de flux et limites

  • Receive Maximum : le nombre de messages QoS 1 et QoS 2 non acquittés qu’une partie accepte de gérer simultanément. Il empêche un broker rapide de submerger un appareil lent. Voir les niveaux de QoS MQTT.
  • Maximum Packet Size : chaque partie peut refuser les paquets au-delà d’une taille qu’elle déclare.
  • Server Keep Alive : le broker peut imposer sa propre valeur de keep-alive au client.
  • Assigned Client Identifier : si vous vous connectez avec un client ID vide, le broker vous communique celui qu’il a généré.

Authentification étendue

L’authentification MQTT 3.1.1 se limite à un nom d’utilisateur et un mot de passe dans le CONNECT (plus les certificats clients TLS au niveau transport). MQTT 5 ajoute un paquet AUTH et les propriétés Authentication Method et Authentication Data, ce qui permet des schémas défi/réponse comme SCRAM ou Kerberos, ainsi que la ré-authentification sur une connexion active sans déconnexion. Le support varie selon les brokers : vérifiez avant de vous appuyer dessus.

Des ajouts plus modestes mais utiles

  • Options d’abonnement : No Local (ne pas me renvoyer mes propres messages), Retain As Published et Retain Handling.
  • Identifiants d’abonnement : savoir quel abonnement a correspondu à un message livré.
  • Will Delay Interval : retarder le Last Will pour qu’une reconnexion rapide ne le déclenche pas.

Faut-il migrer ?

Pour les nouveaux projets, partez sur MQTT 5 : de meilleures erreurs suffisent à économiser des heures de débogage. Conservez la 3.1.1 là où le firmware ou les bibliothèques ne peuvent pas être mis à jour ; rien n’oblige à migrer, et les deux versions coexistent sur le même broker. Lors de la migration, activez la version dans votre client (pour MQTT.js, protocolVersion: 5) et vérifiez que le broker l’accepte.

Se connecter en MQTT 5 dans le navigateur

Vous découvrez le protocole ? Commencez par qu’est-ce que MQTT, ou essayez dès maintenant les deux versions dans le client MQTT en ligne.

Questions fréquentes

MQTT 5 est-il rétrocompatible avec MQTT 3.1.1 ?

Pas au niveau du protocole : les formats de paquets diffèrent et l’octet de niveau de protocole vaut 5 au lieu de 4. En pratique, la plupart des brokers prennent en charge les deux versions simultanément, si bien que des clients MQTT 3.1.1 et MQTT 5 peuvent échanger des messages via le même broker.

Faut-il utiliser MQTT 5 ou 3.1.1 pour un nouveau projet ?

Utilisez MQTT 5 lorsque votre broker et vos bibliothèques clientes le prennent en charge, ce qui est le cas de la plupart des solutions actuelles. Restez en 3.1.1 pour les appareils contraints ou anciens dont le firmware ou les bibliothèques n’implémentent que cette version.

Qu’est devenu MQTT 4 ?

Il n’y a pas de MQTT 4. La version 3.1.1 utilise le niveau de protocole 4 dans le paquet CONNECT : la version suivante a donc été numérotée 5 pour correspondre à son niveau de protocole et éviter toute confusion.