Les paquets de contrôle MQTT sont les 15 types de messages qu'échangent clients et brokers, de CONNECT à AUTH, et toute interaction MQTT se construit à partir d'eux. Cette référence explique ce que fait chaque paquet, qui l'envoie, comment le reconnaître à son premier octet et à quoi il ressemble dans les journaux de débogage d'un client, pour que vous puissiez suivre une conversation avec un broker et repérer précisément où elle déraille.
Les paquets de contrôle MQTT en un coup d'œil
Le type de paquet se trouve dans les quatre bits de poids fort du premier octet de chaque paquet. MQTT 3.1.1 définit les types 1 à 14 ; MQTT 5 ajoute le type 15, AUTH. Le type 0 est réservé et jamais valide.
| Type | Nom | Sens | Premier octet | Rôle |
|---|---|---|---|---|
| 1 | CONNECT | Client vers broker | 0x10 | Ouvrir une session |
| 2 | CONNACK | Broker vers client | 0x20 | Accepter ou refuser la connexion |
| 3 | PUBLISH | Les deux | 0x30-0x3F | Livrer un message applicatif |
| 4 | PUBACK | Les deux | 0x40 | Acquitter une publication QoS 1 |
| 5 | PUBREC | Les deux | 0x50 | QoS 2 étape 1 : publication reçue |
| 6 | PUBREL | Les deux | 0x62 | QoS 2 étape 2 : libération |
| 7 | PUBCOMP | Les deux | 0x70 | QoS 2 étape 3 : fin de l'échange |
| 8 | SUBSCRIBE | Client vers broker | 0x82 | Demander des abonnements |
| 9 | SUBACK | Broker vers client | 0x90 | Accorder ou refuser des abonnements |
| 10 | UNSUBSCRIBE | Client vers broker | 0xA2 | Supprimer des abonnements |
| 11 | UNSUBACK | Broker vers client | 0xB0 | Confirmer le désabonnement |
| 12 | PINGREQ | Client vers broker | 0xC0 | Sonde keep alive |
| 13 | PINGRESP | Broker vers client | 0xD0 | Réponse keep alive |
| 14 | DISCONNECT | Client vers broker (les deux en MQTT 5) | 0xE0 | Fermer proprement la connexion |
| 15 | AUTH | Les deux (MQTT 5 uniquement) | 0xF0 | Échange d'authentification étendue |
Connaître le premier octet est pratique pour lire un dump hexadécimal brut : 0xC0 0x00 est un PINGREQ, 0x82 commence un SUBSCRIBE. La disposition au niveau de l'octet des en-têtes et des payloads est traitée dans le guide de la structure des paquets MQTT.
Observer les paquets de contrôle dans un journal de débogage
Le moyen le plus simple de voir ces paquets est le flag -d des clients Mosquitto. Avec le serveur MQTT public gratuit :
mosquitto_sub -h broker.connectmq.com -p 1883 -i pkt-demo-e41f \
-t "connectmq/demo/e41f/#" -q 1 -k 10 -d
Dans un second terminal, publiez un message :
mosquitto_pub -h broker.connectmq.com -p 1883 -i pkt-pub-e41f \
-t "connectmq/demo/e41f/temp" -m "22.1" -q 1 -d
La sortie du subscriber ressemblera à ceci :
Client pkt-demo-e41f sending CONNECT
Client pkt-demo-e41f received CONNACK (0)
Client pkt-demo-e41f sending SUBSCRIBE (Mid: 1, Topic: connectmq/demo/e41f/#, QoS: 1, Options: 0x00)
Client pkt-demo-e41f received SUBACK
Subscribed (mid: 1): 1
Client pkt-demo-e41f received PUBLISH (d0, q1, r0, m1, 'connectmq/demo/e41f/temp', ... (4 bytes))
Client pkt-demo-e41f sending PUBACK (m1, rc0)
22.1
Client pkt-demo-e41f sending PINGREQ
Client pkt-demo-e41f received PINGRESP
Le keep alive -k 10 fait apparaître un PINGREQ après dix secondes d'inactivité. Dans la ligne PUBLISH, d0, q1, r0, m1 signifie DUP 0, QoS 1, retain 0 et message ID 1. Paho Python affiche des lignes similaires avec client.enable_logger(), et MQTT.js le fait avec la variable d'environnement DEBUG=mqttjs*.
Paquets de connexion : CONNECT, CONNACK, DISCONNECT
CONNECT est toujours le premier paquet envoyé par un client. Il porte la version du protocole, le flag clean session ou clean start, le keep alive, le client ID, un éventuel Last Will et un éventuel nom d'utilisateur et mot de passe. En MQTT 5, il porte aussi des propriétés comme Session Expiry Interval, Receive Maximum et Topic Alias Maximum. Envoyer un second CONNECT sur la même connexion est une erreur de protocole.
CONNACK est la réponse du broker. Il contient le flag Session Present et un return code (3.1.1) ou un reason code (MQTT 5). Les brokers MQTT 5 utilisent aussi les propriétés du CONNACK pour informer le client de leurs limites : Maximum QoS, Maximum Packet Size, Topic Alias Maximum, disponibilité du retain, des wildcards ou des shared subscriptions, et un client ID attribué si le client en a envoyé un vide. Quand une connexion échoue, le CONNACK est le premier endroit à examiner ; consultez les codes de retour CONNACK MQTT.
DISCONNECT ferme proprement la connexion. Un client qui envoie DISCONNECT avant de fermer le socket supprime son message Last Will (sauf en MQTT 5 avec le reason code 0x04). En MQTT 3.1.1, seul le client envoie DISCONNECT ; en MQTT 5, le broker peut aussi en envoyer un, avec un reason code qui explique pourquoi, comme 0x8E Session taken over ou 0x97 Quota exceeded. Si vous observez une boucle de reconnexion, cherchez des DISCONNECT envoyés par le broker ; le guide expliquant pourquoi un client MQTT se déconnecte sans cesse passe en revue les causes.
Paquets de publication : PUBLISH et les acquittements
PUBLISH transporte le message applicatif dans les deux sens : du client vers le broker quand vous publiez, du broker vers le client quand vous recevez. Les flags de son en-tête fixe contiennent DUP, QoS et RETAIN.
Les acquittements dépendent de la QoS, expliquée en détail dans les niveaux de QoS MQTT :
| QoS | Flux de paquets | Nombre total de paquets par message |
|---|---|---|
| 0 | PUBLISH | 1 |
| 1 | PUBLISH, PUBACK | 2 |
| 2 | PUBLISH, PUBREC, PUBREL, PUBCOMP | 4 |
- PUBACK confirme un message QoS 1. Tant qu'il n'est pas arrivé, l'émetteur conserve le message et peut le renvoyer avec DUP activé après une reconnexion.
- PUBREC est le « je l'ai » du récepteur en QoS 2. L'émetteur peut alors abandonner le payload du message.
- PUBREL indique au récepteur qu'il peut libérer le message vers les subscribers, et que le packet ID pourra bientôt être réutilisé.
- PUBCOMP clôt l'échange QoS 2.
Notez que chaque saut est indépendant. Une publication QoS 1 d'un capteur vers le broker et une livraison QoS 2 du broker vers un subscriber sont des échanges distincts. En MQTT 5, ces acquittements portent des reason codes : un PUBACK peut ainsi indiquer 0x10 No matching subscribers ou 0x87 Not authorized.
Paquets d'abonnement : SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK
SUBSCRIBE contient un packet identifier et un ou plusieurs filtres de topics, chacun avec une QoS demandée. MQTT 5 ajoute des options d'abonnement comme No Local, Retain As Published et Retain Handling, ainsi qu'un Subscription Identifier facultatif.
SUBACK renvoie un code par filtre, dans le même ordre. Lisez chaque entrée : un seul SUBSCRIBE avec trois filtres peut réussir pour deux et échouer pour un. En 3.1.1, la valeur d'échec est 0x80 ; MQTT 5 donne des raisons précises comme 0x8F Topic Filter invalid ou 0x9E Shared Subscriptions not supported.
UNSUBSCRIBE et UNSUBACK font de même pour la suppression. MQTT 5 ajoute à UNSUBACK des reason codes par filtre, dont 0x11 No subscription existed.
Paquets keep alive : PINGREQ et PINGRESP
PINGREQ et PINGRESP sont des paquets de deux octets qui prouvent que la connexion est vivante lorsqu'aucun autre trafic ne circule. Le client envoie un PINGREQ s'il n'a rien envoyé pendant l'intervalle de keep alive ; le broker doit répondre par un PINGRESP. Si le broker ne reçoit rien pendant 1,5 fois le keep alive, il ferme la connexion. Si le client ne reçoit pas de PINGRESP dans un délai raisonnable, il doit considérer la connexion comme morte. Le guide de l'intervalle keep alive MQTT explique comment choisir la valeur.
AUTH : l'ajout de MQTT 5
AUTH prend en charge l'authentification étendue, comme les mécanismes de challenge-response, via les propriétés Authentication Method et Authentication Data. Il est utilisé après CONNECT pour des échanges en plusieurs étapes et peut aussi lancer une ré-authentification sur une connexion existante. La plupart des déploiements, y compris ceux qui utilisent nom d'utilisateur et mot de passe, n'envoient jamais d'AUTH : le voir dans une capture est donc inhabituel, sauf si vous avez configuré une méthode étendue.
Check-list de débogage par paquet
- Pas de CONNACK ? Le problème vient du réseau, du port ou de TLS, pas de MQTT.
- CONNACK avec un code non nul ? Identifiants, client ID ou version du protocole.
- SUBACK avec 0x80 ou plus ? Filtre incorrect, permission ou fonctionnalité non prise en charge.
- PUBLISH envoyé mais pas de PUBACK ? Vérifiez la prise en charge de la QoS et l'état de la connexion.
- PINGREQ répétés sans PINGRESP ? La connexion est à moitié morte ; reconnectez-vous.
- DISCONNECT inattendu du broker ? Lisez son reason code.
Voir chaque paquet sur ConnectMQ
ConnectMQ prend en charge MQTT 3.1.1 et 5.0 : vous pouvez donc observer à la fois le flux de paquets classique et les reason codes et propriétés de MQTT 5 sur le même broker. Pour une vue d'ensemble, découvrez ce que fait un broker MQTT de ces paquets, ou suivez le tutoriel MQTT complet.
Construire sur ConnectMQ
Quand vous passez des expérimentations aux appareils, un broker MQTT managé s'occupe de TLS, des identifiants et de la disponibilité. Créez un broker Serverless gratuit sur app.connectmq.com sans carte bancaire, puis utilisez le client intégré au navigateur et l'explorateur de topics en direct du portail pendant votre débogage. Vous pouvez aussi comparer les options dans notre guide du marché des brokers MQTT cloud.
Questions fréquentes
Combien existe-t-il de types de paquets de contrôle MQTT ?
MQTT 5 définit 15 types de paquets de contrôle, numérotés de 1 à 15. MQTT 3.1.1 en compte 14, car le paquet AUTH a été ajouté avec MQTT 5.
Quels paquets un message QoS 2 utilise-t-il ?
PUBLISH, PUBREC, PUBREL et PUBCOMP. La poignée de main en quatre étapes garantit que le message est livré exactement une fois entre cet émetteur et ce récepteur.
Le broker peut-il envoyer un paquet DISCONNECT ?
Uniquement en MQTT 5. En MQTT 3.1.1, le broker ferme simplement la connexion réseau ; MQTT 5 lui permet d'envoyer d'abord un DISCONNECT avec un reason code.
Pourquoi vois-je des PINGREQ dans mes journaux ?
Le PINGREQ est la sonde keep alive du client, envoyée lorsqu'il est resté inactif pendant l'intervalle de keep alive. Des paires PINGREQ et PINGRESP régulières sont normales et montrent que la connexion est en bonne santé.



