Fondamentaux MQTT

Session Expiry Interval et Clean Start dans MQTT 5 expliqués

MQTT 5 a scindé l'ancien flag clean session en Clean Start et Session Expiry Interval. Voici comment les deux se combinent, quelles valeurs choisir et comment les vérifier sur un broker réel.

Illustration du Session Expiry Interval MQTT avec un compte à rebours sur une session du broker après la déconnexion d'un client IoT
Essayez-le sur votre propre broker MQTTObtenez un broker MQTT privé et managé avec l’offre Free et partez d’exemples de code prêts à l’emploi.
Essayer gratuitement Exemples de code Aucune carte bancaire requise

Le Session Expiry Interval MQTT indique au broker combien de temps conserver la session d'un client après sa déconnexion ; associé au flag Clean Start, il remplace le flag clean session de MQTT 3.1.1, qui fonctionnait en tout ou rien. Dans cet article, vous verrez comment les deux paramètres se combinent, comment l'intervalle peut être modifié au moment de la déconnexion et comment choisir des valeurs pertinentes pour les capteurs, les passerelles et les services backend.

Pourquoi MQTT 5 a remplacé le flag Clean Session

Dans MQTT 3.1.1, cleanSession remplissait deux rôles avec un seul bit. Le mettre à false signifiait « reprends mon ancienne session et conserve celle-ci pour toujours ». Impossible de dire « reprends ma session, mais oublie-la si je suis absent plus d'une heure ». Les brokers contournaient le problème avec des réglages d'expiration côté serveur, si bien que le comportement variait d'un broker à l'autre et que les sessions abandonnées s'accumulaient.

MQTT 5 sépare les deux préoccupations :

  • Clean Start (un flag du CONNECT) répond à la question : le broker doit-il supprimer immédiatement toute session existante ?
  • Session Expiry Interval (une propriété du CONNECT, en secondes) répond à la question : combien de temps la session doit-elle vivre après la fermeture de la connexion réseau ?

Ce fonctionnement est décrit dans la spécification OASIS MQTT 5.0, et c'est l'une des améliorations les plus concrètes présentées dans notre tour d'horizon des fonctionnalités de MQTT 5.

Comment Clean Start et Session Expiry se combinent

Clean Start Session Expiry Interval Comportement Équivalent 3.1.1
true 0 (ou absent) Nouvelle session, supprimée à la déconnexion cleanSession = true
false 0 (ou absent) Reprise de la session existante s'il y en a une, supprimée à la déconnexion Pas d'équivalent direct
true > 0 Suppression de l'ancienne session, nouvelle session qui survit N secondes à la déconnexion Pas d'équivalent direct
false > 0 Reprise si elle existe, survie de N secondes après la déconnexion cleanSession = false (avec un délai)
false 0xFFFFFFFF Reprise si elle existe, aucune expiration cleanSession = false

Quelques détails comptent en pratique :

  • Le minuteur démarre à la fermeture de la connexion réseau, et non à la dernière publication du client.
  • Si le client se reconnecte avant la fin du minuteur, la session est reprise et le minuteur annulé.
  • Lorsque l'intervalle s'est écoulé, le broker supprime les abonnements et tous les messages en file d'attente.
  • Si la session expire, le message de testament (will) est envoyé au plus tard à ce moment-là, même si le will delay interval est plus long.

Modifier l'intervalle à la déconnexion

MQTT 5 permet à un client de mettre à jour l'expiration dans son paquet DISCONNECT. Un appareil qui part en maintenance planifiée peut ainsi dire « garde ma session pendant une journée » en se déconnectant, tout en fonctionnant normalement avec une valeur plus courte. Une seule restriction : si le client s'est connecté avec une expiration de 0, il ne peut pas définir de valeur non nulle à la déconnexion ; le broker considère cela comme une erreur de protocole.

Le broker peut imposer sa valeur

Un broker peut refuser de conserver les sessions aussi longtemps que vous le demandez. Dans ce cas, il renvoie une propriété Session Expiry Interval dans le CONNACK, et c'est cette valeur qui s'applique. Journalisez toujours les propriétés du CONNACK pendant le développement pour connaître la valeur réelle. Sur le serveur MQTT public gratuit broker.connectmq.com, réservé aux tests et aux prototypes, l'expiration de session est plafonnée à 30 minutes.

Choisir un Session Expiry Interval MQTT

Posez-vous deux questions : combien de temps ce client peut-il réalistement rester hors ligne, et à partir de quel âge un message en file d'attente devient-il inutile ?

Type de client Expiration suggérée Justification
Tableau de bord en direct, onglet de navigateur 0 Seules les données actuelles comptent ; les retained messages remplissent l'écran à la connexion
Capteur sur secteur qui ne fait que publier 0 à 300 s Peu d'état de session ; une expiration courte fait le ménage rapidement
Appareil qui reçoit des commandes 1 à 24 h Les commandes doivent survivre aux coupures Wi-Fi et aux courtes pannes
Appareil sur batterie qui se réveille toutes les heures Un peu plus long que l'intervalle de réveil La session doit survivre à la période de veille
Worker backend qui traite des alarmes Plusieurs heures, selon votre temps de reprise Les alarmes manquées doivent être traitées après un redéploiement
Client mis hors service ou de test 0 Évite de laisser des sessions orphelines

Associez les intervalles d'expiration longs à la propriété Message Expiry Interval de MQTT 5 sur les publications sensibles au temps. Une commande « démarrer la pompe » restée six heures en file d'attente peut être plus dangereuse qu'une commande jamais livrée.

Exemple concret : capteur en veille qui reçoit des commandes

Imaginez un capteur sur batterie qui se réveille toutes les 15 minutes, publie une mesure, vérifie s'il a reçu des commandes de configuration puis se rendort. Si son expiration de session était de 0, toute commande envoyée pendant sa veille serait perdue, faute de session dans laquelle la mettre en file. Si l'expiration était infinie, un capteur tombé en panne sur le terrain laisserait une session qui continue d'accumuler des commandes que personne ne lira. Une valeur d'environ 20 à 30 minutes couvre un réveil manqué plus une certaine instabilité réseau, et la session disparaît d'elle-même une fois l'appareil réellement hors service. Envoyez les commandes en QoS 1 avec une expiration de message de quelques heures, et l'appareil recevra tout ce qui est encore pertinent à sa prochaine connexion.

Définir l'expiration de session dans le code

Tous les exemples utilisent un préfixe de démonstration unique sur le serveur MQTT public gratuit. Remplacez s4e8 par votre propre chaîne aléatoire ; l'espace public est visible par tous.

mosquitto_sub

# Reprendre (ou créer) une session qui survit 10 minutes après la déconnexion
mosquitto_sub -h broker.connectmq.com -p 1883 -V mqttv5 \
  -i expiry-demo-s4e8 -c -x 600 -q 1 -v -d \
  -t 'connectmq/demo/s4e8/commands/#'

-c met Clean Start à false, et -x 600 définit le Session Expiry Interval. L'option -d affiche le CONNACK, ce qui vous permet de voir si le broker a accordé la valeur.

Python (paho-mqtt 2.x)

import paho.mqtt.client as mqtt
from paho.mqtt.properties import Properties
from paho.mqtt.packettypes import PacketTypes

def on_connect(client, userdata, flags, reason_code, properties):
    granted = getattr(properties, "SessionExpiryInterval", None)
    print("Connected:", reason_code,
          "| session present:", flags.session_present,
          "| broker override:", granted)
    if not flags.session_present:
        client.subscribe("connectmq/demo/s4e8/commands/#", qos=1)

def on_message(client, userdata, msg):
    print("Command:", msg.topic, msg.payload.decode())

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id="expiry-py-s4e8",
                     protocol=mqtt.MQTTv5)
client.on_connect = on_connect
client.on_message = on_message

connect_props = Properties(PacketTypes.CONNECT)
connect_props.SessionExpiryInterval = 600

client.connect("broker.connectmq.com", 1883, keepalive=60,
               clean_start=False, properties=connect_props)
client.loop_start()

try:
    input("Press Enter to disconnect with a 30 minute expiry...\n")
finally:
    bye = Properties(PacketTypes.DISCONNECT)
    bye.SessionExpiryInterval = 1800
    client.disconnect(properties=bye)
    client.loop_stop()

Node.js (MQTT.js v5)

const mqtt = require("mqtt");

const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  clientId: "expiry-node-s4e8",
  protocolVersion: 5,
  clean: false, // Clean Start = false
  properties: { sessionExpiryInterval: 600 },
});

client.on("connect", (connack) => {
  console.log("session present:", connack.sessionPresent,
              "props:", connack.properties);
  if (!connack.sessionPresent) {
    client.subscribe("connectmq/demo/s4e8/commands/#", { qos: 1 });
  }
});

client.on("message", (topic, payload) => {
  console.log(topic, payload.toString());
});

Erreurs courantes et comment les repérer

  1. Clean Start à false, expiration à 0. Les développeurs portent du code 3.1.1, définissent clean: false et oublient la propriété d'expiration. En MQTT 5, cette session est supprimée dès que la connexion tombe : rien n'est jamais mis en file. Si les messages en attente n'arrivent jamais, vérifiez ce point en premier.
  2. Expiration infinie sur les clients de test. Chaque script jetable avec un ID unique et 0xFFFFFFFF laisse une session derrière lui. Utilisez 0 pour vos expériences, sauf si vous testez justement les sessions.
  3. Ignorer Session Present. Si le broker a redémarré ou si la session a expiré, Session Present vaut 0 et vos abonnements ont disparu. Réabonnez-vous toujours dans ce cas.
  4. Supposer une durabilité après un redémarrage du broker. L'expiration de session décrit combien de temps une session peut vivre, ce n'est pas une garantie de stockage. ConnectMQ conserve l'état des sessions en mémoire : il survit aux déconnexions des clients pendant l'intervalle accordé, mais il est effacé si le broker lui-même redémarre.
  5. Changer de client ID. L'expiration est liée au client ID. Un nouvel ID correspond à une nouvelle session ; consultez les bonnes pratiques pour le client ID MQTT.

Comment cela s'inscrit dans l'ensemble

L'expiration de session est la manière MQTT 5 d'utiliser les sessions persistantes en toute sécurité : vous bénéficiez de la mise en file hors ligne là où vous en avez besoin et d'un nettoyage automatique ailleurs. Si vous découvrez encore les rouages du protocole, le tutoriel MQTT complet est une bonne lecture complémentaire.

Utiliser les sessions MQTT 5 sur ConnectMQ

ConnectMQ est un broker MQTT managé avec une prise en charge complète de MQTT 5.0, y compris l'expiration de session, l'expiration des messages, les alias de topic et les reason codes. Vous pouvez tester les combinaisons de Clean Start et d'expiration avec le client MQTT intégré au navigateur du portail ou avec votre propre code, puis reporter les mêmes réglages en production. Commencez avec l'offre Serverless gratuite, sans carte bancaire, et connectez-vous avec vos identifiants générés YOUR_USERNAME, YOUR_PASSWORD et YOUR_CLIENT_ID.

Questions fréquentes

Quel est le Session Expiry Interval MQTT par défaut ?

Si la propriété est absente, le Session Expiry Interval vaut 0, ce qui signifie que la session prend fin à la fermeture de la connexion réseau. Vous devez le définir explicitement pour obtenir une session persistante en MQTT 5.

Quelle est la différence entre Clean Start et clean session ?

Dans MQTT 3.1.1, clean session contrôlait à la fois la suppression de l'ancienne session et la conservation de la nouvelle. Dans MQTT 5, Clean Start ne contrôle que la suppression au moment de la connexion, tandis que le Session Expiry Interval détermine la durée de vie de la session ensuite.

Quel est le Session Expiry Interval maximal ?

Le maximum du protocole est de 4 294 967 295 secondes (0xFFFFFFFF), ce qui signifie que la session n'expire jamais. Les brokers peuvent imposer des limites plus basses et les indiquer dans le CONNACK ; le serveur MQTT public gratuit de ConnectMQ autorise jusqu'à 30 minutes.

Puis-je modifier l'expiration de session lors de la déconnexion ?

Oui, en envoyant une propriété Session Expiry Interval dans le DISCONNECT, sauf si vous vous êtes initialement connecté avec une expiration de 0.

Articles liés

Qui a inventé MQTT ? L'histoire, des oléoducs à l'IoT

MQTT a été inventé en 1999 par Andy Stanford-Clark (IBM) et Arlen Nipper (Arcom) pour surveiller des oléoducs par satellite. Suivez son parcours vers l'open source, OASIS, l'ISO et les brokers MQTT managés d'aujourd'hui.

8 min de lecture

Pourquoi votre client MQTT se déconnecte sans cesse (et comment y remédier)

Les boucles de reconnexion sont l'un des problèmes MQTT les plus courants. Découvrez les cinq causes habituelles, des client ID en double aux timeouts de keep alive et aux paquets trop volumineux, et suivez une méthode de diagnostic qui identifie la vôtre.

9 min de lecture

Taille maximale d'un message MQTT : limites et stratégies pour les gros payloads

MQTT peut techniquement transporter un paquet de 256 Mo, mais les brokers, les bibliothèques clientes et les appareils imposent des limites bien plus basses. Découvrez où se trouvent les vraies limites, ce qui se passe quand on les dépasse et comment envoyer de gros payloads.

8 min de lecture

Tous les articles →

Votre broker MQTT privé, à quelques clics

Créez un compte, récupérez les identifiants de votre broker et connectez votre premier appareil — aucun serveur à installer, mettre à jour ou dimensionner.