Fondamentaux MQTT

Will Delay Interval MQTT : comment éviter les fausses alertes hors ligne

Un appareil qui perd le Wi-Fi pendant trois secondes ne devrait pas réveiller votre ingénieur d'astreinte. Le will delay interval de MQTT 5 retient le message Last Will assez longtemps pour permettre une reconnexion rapide.

Illustration du Will Delay Interval MQTT avec un minuteur qui retient un message Last Will hors ligne pendant qu'un appareil IoT se reconnecte rapidement
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 Will Delay Interval MQTT est une propriété de MQTT 5 qui demande au broker d'attendre un certain nombre de secondes avant de publier le message Last Will d'un client, et de l'annuler complètement si le client se reconnecte à temps. Dans cet article, vous verrez comment il supprime les alertes hors ligne parasites dues à de brèves coupures réseau, comment il interagit avec l'expiration de session et comment le configurer dans mosquitto, Python et Node.js.

Le problème : des alertes hors ligne qui clignotent

Le Last Will and Testament est le mécanisme intégré de MQTT pour annoncer qu'un client a disparu. Le client enregistre un message de testament à la connexion, généralement un offline retenu sur un topic de statut, et le broker le publie si la connexion se termine sans DISCONNECT propre.

En MQTT 3.1.1, le testament est publié dès que le broker détecte la défaillance. Sur les réseaux réels, cela génère beaucoup de bruit :

  • Un point d'accès Wi-Fi fait basculer un appareil vers un autre point d'accès et la connexion TCP est réinitialisée.
  • Un modem cellulaire renégocie et l'appareil revient en quelques secondes.
  • Une passerelle redémarre son processus MQTT après un changement de configuration.

Chaque cas produit un message offline suivi quelques instants plus tard d'un online. Les tableaux de bord clignotent, les règles d'alerte se déclenchent et les opérateurs apprennent à ignorer les alertes, ce qui est pire que de ne pas en avoir.

Comment fonctionne le Will Delay Interval MQTT

MQTT 5 ajoute le Will Delay Interval, une propriété de quatre octets exprimée en secondes, attachée au message de testament dans le CONNECT. Lorsque la connexion réseau se ferme anormalement :

  1. Le broker démarre un minuteur correspondant au will delay interval.
  2. Si le même client se reconnecte à la même session avant l'expiration du minuteur, le testament n'est pas publié.
  3. Si le minuteur expire en premier, le testament est publié comme d'habitude.
  4. Si la session se termine en premier (parce que le session expiry interval s'est écoulé), le testament est publié à ce moment-là.

La valeur par défaut est 0, ce qui reproduit le comportement de 3.1.1 : une publication immédiate.

La règle que tout le monde oublie : l'expiration de session

Le testament est publié lorsque le délai est écoulé ou lorsque la session se termine, selon ce qui arrive en premier. Si le client se connecte avec un session expiry interval de 0, la session se termine à l'instant où la connexion se ferme : le testament part donc immédiatement et votre délai n'a aucun effet.

Will delay Session expiry Résultat
0 quelconque Testament immédiat en cas de déconnexion anormale
30 s 0 Testament immédiat (la session s'est terminée en premier)
30 s 60 s Testament après 30 s sauf si le client se reconnecte
30 s 10 s Testament après 10 s (la session s'est terminée en premier)
300 s 3600 s Testament après 5 minutes sauf si le client se reconnecte

Pour utiliser le will delay, définissez donc toujours un session expiry interval au moins aussi long que le délai, et reconnectez-vous avec Clean Start à false pour que le broker considère la nouvelle connexion comme la même session. Les détails figurent dans Clean Start et Session Expiry Interval dans MQTT 5.

Le keep alive s'ajoute au total

Le minuteur ne démarre qu'une fois que le broker remarque que la connexion a disparu. Si un appareil perd son alimentation, la détection prend jusqu'à 1,5 fois le keep alive. Avec un keep alive de 60 secondes et un will delay de 30 secondes, le délai maximal avant un message hors ligne est d'environ deux minutes. Prévoyez les deux ensemble ; consultez choisir l'intervalle de keep alive MQTT.

Choisir une valeur de will delay

Choisissez le délai le plus court qui couvre votre temps de reconnexion habituel.

  • Appareils Wi-Fi avec une logique de reconnexion rapide : 10 à 30 secondes.
  • Appareils cellulaires : 30 à 120 secondes ; le réenregistrement du modem est plus lent.
  • Passerelles qui redémarrent des services lors des mises à jour : un peu plus long qu'un redémarrage type.
  • Équipements liés à la sécurité : gardez-le court, voire à 0. Une alarme retardée peut coûter plus cher qu'une fausse alarme.

Un test pratique : journalisez le temps entre déconnexion et reconnexion pendant une semaine de fonctionnement réel, puis choisissez une valeur juste au-dessus de la majorité de ces écarts.

Configurer le will delay dans le code

Tous les exemples utilisent le serveur MQTT public gratuit broker.connectmq.com. Remplacez w3d8 par votre propre chaîne aléatoire et n'oubliez pas que l'espace public est lisible par tous : réservez-le aux tests et aux prototypes.

mosquitto_sub comme appareil simulé

mosquitto_sub -h broker.connectmq.com -p 1883 -V mqttv5 \
  -i willdelay-dev-w3d8 -c -x 120 \
  --will-topic 'connectmq/demo/w3d8/status' \
  --will-payload 'offline' --will-qos 1 --will-retain \
  -D will will-delay-interval 30 \
  -t 'connectmq/demo/w3d8/cmd'

Dans un autre terminal, surveillez le topic de statut :

mosquitto_sub -h broker.connectmq.com -p 1883 -i willdelay-watch-w3d8 \
  -v -t 'connectmq/demo/w3d8/status'

Un Ctrl+C sur mosquitto_sub envoie un DISCONNECT propre, qui ne déclenche jamais de testament. Pour simuler une vraie panne, tuez plutôt le processus (par exemple avec kill -9 sur son identifiant de processus, ou en débranchant le réseau). Essayez ensuite deux cas : relancez la commande de l'appareil en moins de 30 secondes et aucun offline n'apparaît ; attendez plus longtemps et il apparaît.

Python (paho-mqtt 2.x)

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

STATUS = "connectmq/demo/w3d8/status"

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id="willdelay-py-w3d8",
                     protocol=mqtt.MQTTv5)

will_props = Properties(PacketTypes.WILLMESSAGE)
will_props.WillDelayInterval = 30          # secondes
client.will_set(STATUS, payload="offline", qos=1, retain=True,
                properties=will_props)

def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    # Annonce que nous sommes en ligne (écrase un "offline" retenu)
    client.publish(STATUS, "online", qos=1, retain=True)

client.on_connect = on_connect

connect_props = Properties(PacketTypes.CONNECT)
connect_props.SessionExpiryInterval = 120  # doit être >= will delay

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

Node.js (MQTT.js v5)

const mqtt = require("mqtt");
const STATUS = "connectmq/demo/w3d8/status";

const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  clientId: "willdelay-node-w3d8",
  protocolVersion: 5,
  clean: false,
  keepalive: 30,
  properties: { sessionExpiryInterval: 120 },
  will: {
    topic: STATUS,
    payload: Buffer.from("offline"),
    qos: 1,
    retain: true,
    properties: { willDelayInterval: 30 },
  },
});

client.on("connect", () => {
  client.publish(STATUS, "online", { qos: 1, retain: true });
});

Un modèle complet en ligne / hors ligne

Le will delay fonctionne au mieux dans le cadre d'une conception de présence cohérente :

  1. Enregistrez un testament offline retenu avec un will delay et une expiration de session adaptée.
  2. Publiez un online retenu immédiatement après chaque connexion réussie.
  3. Avant un arrêt planifié, publiez vous-même un offline retenu, puis déconnectez-vous proprement.
  4. Faites en sorte que les tableaux de bord et les règles d'alerte ne lisent que le topic de statut retenu.
  5. Ajoutez éventuellement un horodatage ou une raison dans un payload JSON pour que les opérateurs sachent pourquoi un appareil est passé hors ligne.

D'autres modèles de présence sont présentés dans le statut en ligne des appareils MQTT. Sur un broker ConnectMQ, vous pouvez aussi recouper avec le topic $SYS/broker/connection/{clientId}/state, qui reflète la vue du broker sur la connexion brute plutôt que votre statut applicatif.

Will delay ou anti-rebond dans l'application

Avant MQTT 5, les équipes réglaient le problème des oscillations par un anti-rebond côté consommateur : un tableau de bord ou un service d'alerte attendait N secondes après un message offline et ne déclenchait une alarme que si aucun online ne suivait. Cela fonctionne toujours, mais chaque consommateur doit implémenter la même logique, et chacun peut choisir une fenêtre différente. Le will delay déplace la décision dans le broker : tous les abonnés voient ainsi le même flux de statut, déjà filtré. La contrepartie est que le délai est défini par client au moment de la connexion : le modifier implique de mettre à jour la configuration des appareils plutôt qu'un seul service backend.

Dépanner le will delay

  • Le testament part toujours immédiatement : l'expiration de session vaut 0 ou est plus courte que le will delay, ou vous vous connectez en MQTT 3.1.1.
  • Le testament part alors que l'appareil s'est reconnecté rapidement : l'appareil s'est reconnecté avec Clean Start à true ou avec un autre client ID ; il s'agissait donc d'une nouvelle session.
  • Le testament ne part jamais : le client s'est déconnecté proprement, ou le délai est plus long que votre attente. N'oubliez pas d'ajouter le temps de détection du keep alive.
  • Un offline périmé s'affiche après la reconnexion : publiez un online retenu à chaque connexion, pas seulement à la première.

Vous découvrez ces notions ? Le tutoriel MQTT explique depuis le début les testaments, les sessions et les retained messages.

Construire un statut d'appareil fiable sur ConnectMQ

ConnectMQ est un broker MQTT managé avec une prise en charge complète de MQTT 5.0, y compris les propriétés du testament, l'expiration de session et les retained messages. Son portail ajoute des règles d'alerte à seuil et un journal des alertes : des données de statut plus propres au niveau du protocole signifient donc moins d'alertes parasites issues des règles que vous construisez dessus. Commencez gratuitement avec l'offre Serverless, sans carte bancaire, connectez-vous avec YOUR_USERNAME, YOUR_PASSWORD et YOUR_CLIENT_ID, et testez vos réglages de will delay sur votre propre broker.

Questions fréquentes

Quel est le Will Delay Interval MQTT par défaut ?

La valeur par défaut est de 0 seconde : le message de testament est publié dès que le broker détecte une déconnexion anormale, exactement comme en MQTT 3.1.1.

Pourquoi mon message de testament ignore-t-il le délai ?

Le plus souvent, le session expiry interval vaut 0 ou est plus court que le will delay. Le broker publie le testament à la fin de la session : celle-ci doit donc durer au moins aussi longtemps que le délai.

Le will delay est-il disponible en MQTT 3.1.1 ?

Non. C'est une fonctionnalité de MQTT 5. Avec MQTT 3.1.1, il faudrait plutôt appliquer un anti-rebond aux événements hors ligne dans l'application consommatrice.

Une déconnexion propre déclenche-t-elle le message de testament ?

Non. Un DISCONNECT normal supprime le testament. En MQTT 5, un client peut délibérément demander l'envoi du testament en se déconnectant avec le reason code 0x04 (Disconnect with Will Message).

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.