Das MQTT Will Delay Interval ist eine MQTT-5-Property, die den Broker anweist, eine bestimmte Anzahl Sekunden zu warten, bevor er die Last-Will-Nachricht eines Clients veröffentlicht, und sie ganz zu verwerfen, wenn sich der Client rechtzeitig neu verbindet. In diesem Artikel sehen Sie, wie es lästige Offline-Alarme durch kurze Netzwerkaussetzer unterdrückt, wie es mit der Session Expiry zusammenspielt und wie Sie es in mosquitto, Python und Node.js konfigurieren.
Das Problem: flackernde Offline-Alarme
Last Will and Testament ist der eingebaute Weg von MQTT, das Verschwinden eines Clients zu melden. Der Client registriert beim Verbindungsaufbau eine Will Message, typischerweise ein retained offline auf einem Status-Topic, und der Broker veröffentlicht sie, wenn die Verbindung ohne sauberes DISCONNECT endet.
In MQTT 3.1.1 wird der Will veröffentlicht, sobald der Broker den Ausfall erkennt. In echten Netzwerken ist das unruhig:
- Ein WLAN-Access-Point übergibt ein Gerät per Roaming an einen anderen AP, und die TCP-Verbindung wird zurückgesetzt.
- Ein Mobilfunkmodem verhandelt neu, und das Gerät ist nach wenigen Sekunden wieder da.
- Ein Edge-Gateway an einer SPS in der Fertigungslinie startet nach einer Konfigurationsänderung seinen MQTT-Prozess neu.
Jeder Fall erzeugt eine offline-Nachricht, gefolgt von online wenige Augenblicke später. Dashboards flackern, Alarmregeln schlagen an, Leitstand und Instandhaltung erhalten Stillstandsmeldungen für Maschinen, die nie stillstanden, und das Betriebsteam lernt, die Alarme zu ignorieren, was schlimmer ist, als gar keine zu haben.
So funktioniert das MQTT Will Delay Interval
MQTT 5 ergänzt das Will Delay Interval, eine Vier-Byte-Property in Sekunden, die im CONNECT an die Will Message angehängt wird. Wird die Netzwerkverbindung unsauber geschlossen:
- Der Broker startet einen Timer über das Will Delay Interval.
- Verbindet sich derselbe Client vor Ablauf des Timers wieder mit derselben Session, wird der Will nicht veröffentlicht.
- Läuft zuerst der Timer ab, wird der Will wie gewohnt veröffentlicht.
- Endet zuerst die Session (weil das Session Expiry Interval abgelaufen ist), wird der Will in diesem Moment veröffentlicht.
Der Standardwert ist 0, was das Verhalten von 3.1.1 mit sofortiger Veröffentlichung nachbildet.
Die Regel, die alle übersehen: Session Expiry
Der Will wird veröffentlicht, wenn die Verzögerung verstrichen ist oder die Session endet, je nachdem, was zuerst eintritt. Verbindet sich der Client mit einem Session Expiry Interval von 0, endet die Session in dem Moment, in dem die Verbindung geschlossen wird; der Will geht also sofort raus, und Ihre Verzögerung bleibt wirkungslos.
| Will Delay | Session Expiry | Ergebnis |
|---|---|---|
| 0 | beliebig | Sofortiger Will bei unsauberer Trennung |
| 30 s | 0 | Sofortiger Will (Session endete zuerst) |
| 30 s | 60 s | Will nach 30 s, sofern sich der Client nicht neu verbindet |
| 30 s | 10 s | Will nach 10 s (Session endete zuerst) |
| 300 s | 3600 s | Will nach 5 Minuten, sofern sich der Client nicht neu verbindet |
Wenn Sie Will Delay nutzen, setzen Sie also immer ein Session Expiry Interval, das mindestens so lang ist wie die Verzögerung, und verbinden Sie sich mit Clean Start auf false neu, damit der Broker die neue Verbindung als dieselbe Session behandelt. Details finden Sie unter MQTT 5 Clean Start und Session Expiry Interval.
Keep Alive kommt noch hinzu
Der Timer startet erst, wenn der Broker bemerkt, dass die Verbindung weg ist. Verliert ein Gerät die Stromversorgung, dauert die Erkennung bis zum 1,5-Fachen des Keep Alive. Mit 60 Sekunden Keep Alive und 30 Sekunden Will Delay vergehen im schlimmsten Fall etwa zwei Minuten bis zur Offline-Nachricht. Planen Sie beides gemeinsam ein; siehe das passende MQTT Keep Alive Interval wählen.
Den passenden Will-Delay-Wert wählen
Wählen Sie die kürzeste Verzögerung, die Ihre normale Reconnect-Zeit abdeckt.
- WLAN-Geräte mit schneller Reconnect-Logik: 10 bis 30 Sekunden.
- Mobilfunkgeräte: 30 bis 120 Sekunden; die Neuregistrierung des Modems dauert länger.
- Gateways, die bei Updates Dienste neu starten: etwas länger als ein typischer Neustart.
- Sicherheitsrelevante Anlagen: kurz halten oder 0. Ein verzögerter Alarm kann teurer sein als ein falscher.
Ein praxisnaher Test: Protokollieren Sie eine Woche lang im realen Betrieb die Zeit zwischen Trennung und Reconnect und wählen Sie einen Wert knapp oberhalb des Großteils dieser Lücken.
Will Delay im Code konfigurieren
Alle Beispiele nutzen den öffentlichen MQTT-Broker unter broker.connectmq.com, der für Tests und Prototypen gedacht ist, nicht für Produktionsdaten. Ersetzen Sie w3d8 durch eine eigene Zufallszeichenfolge und denken Sie daran, dass der öffentliche Bereich für alle lesbar ist.
mosquitto_sub als simuliertes Gerät
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'
Beobachten Sie in einem anderen Terminal das Status-Topic:
mosquitto_sub -h broker.connectmq.com -p 1883 -i willdelay-watch-w3d8 \
-v -t 'connectmq/demo/w3d8/status'
Strg+C bei mosquitto_sub sendet ein sauberes DISCONNECT, das niemals einen Will auslöst. Um einen echten Ausfall zu simulieren, beenden Sie stattdessen den Prozess hart (zum Beispiel mit kill -9 auf seine Prozess-ID oder indem Sie das Netzwerk trennen). Probieren Sie dann zwei Fälle aus: Starten Sie den Gerätebefehl innerhalb von 30 Sekunden neu, erscheint kein offline; warten Sie länger, erscheint es.
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 # Sekunden
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)
# Online melden (überschreibt ein retained "offline")
client.publish(STATUS, "online", qos=1, retain=True)
client.on_connect = on_connect
connect_props = Properties(PacketTypes.CONNECT)
connect_props.SessionExpiryInterval = 120 # muss >= Will Delay sein
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 });
});
Ein vollständiges Online/Offline-Muster
Will Delay funktioniert am besten als Teil eines konsistenten Präsenzdesigns:
- Registrieren Sie einen retained
offline-Will mit Will Delay und passender Session Expiry. - Veröffentlichen Sie nach jedem erfolgreichen Verbindungsaufbau sofort ein retained
online. - Veröffentlichen Sie vor einem geplanten Herunterfahren selbst ein retained
offlineund trennen Sie dann sauber. - Lassen Sie Dashboards und Alarmregeln nur das retained Status-Topic lesen.
- Ergänzen Sie optional einen Zeitstempel oder Grund in einer JSON-Payload, damit das Betriebsteam sieht, warum ein Gerät offline ging.
Weitere Präsenzmuster behandelt der Artikel zum Online-Status von MQTT-Geräten. Auf einem ConnectMQ-Broker können Sie zusätzlich mit dem Topic $SYS/broker/connection/{clientId}/state gegenprüfen, das die Sicht des Brokers auf die reine Verbindung widerspiegelt statt Ihres Status auf Anwendungsebene.
Will Delay oder Entprellen in der Anwendung
Vor MQTT 5 lösten Teams das Flackern durch Entprellen im Consumer: Ein Dashboard oder Alarmdienst wartete nach einer offline-Nachricht N Sekunden und löste nur dann einen Alarm aus, wenn kein online folgte. Das funktioniert weiterhin, aber jeder Consumer muss dieselbe Logik implementieren, und jeder wählt womöglich ein anderes Zeitfenster. Will Delay verlagert die Entscheidung in den Broker, sodass jeder Subscriber denselben, bereits gefilterten Statusstrom sieht. Der Nachteil: Die Verzögerung wird pro Client beim Verbindungsaufbau festgelegt, eine Änderung erfordert also eine Anpassung der Gerätekonfiguration statt eines einzelnen Backend-Dienstes.
Fehlerbehebung beim Will Delay
- Der Will wird trotzdem sofort ausgelöst: Die Session Expiry ist 0 oder kürzer als das Will Delay, oder Sie verbinden sich mit MQTT 3.1.1.
- Der Will wird ausgelöst, obwohl sich das Gerät schnell neu verbunden hat: Das Gerät hat sich mit Clean Start true oder einer anderen Client-ID neu verbunden, es war also eine neue Session.
- Der Will wird nie ausgelöst: Der Client hat sich sauber getrennt, oder die Verzögerung ist länger, als Sie gewartet haben. Denken Sie an die zusätzliche Erkennungszeit durch Keep Alive.
- Nach dem Reconnect wird ein veraltetes
offlineangezeigt: Veröffentlichen Sie bei jedem Verbindungsaufbau ein retainedonline, nicht nur beim ersten.
Neu bei diesen Konzepten? Das MQTT-Tutorial erklärt Wills, Sessions und Retained Messages von Anfang an.
Zuverlässigen Gerätestatus mit ConnectMQ aufbauen
ConnectMQ ist ein verwalteter MQTT-Broker mit vollständiger MQTT-5.0-Unterstützung, einschließlich Will-Properties, Session Expiry und Retained Messages. Das Portal bietet zusätzlich schwellenwertbasierte Alarmregeln und ein Alarmprotokoll; sauberere Statusdaten auf Protokollebene bedeuten also weniger Fehlalarme aus den Regeln, die Sie darauf aufbauen. Starten Sie kostenlos mit dem Serverless-Tarif, ohne Kreditkarte, verbinden Sie sich mit YOUR_USERNAME, YOUR_PASSWORD und YOUR_CLIENT_ID und testen Sie Ihre Will-Delay-Einstellungen auf Ihrem eigenen Broker.
Häufig gestellte Fragen
Was ist der Standardwert des MQTT Will Delay Interval?
Der Standardwert ist 0 Sekunden, das heißt, die Will Message wird veröffentlicht, sobald der Broker eine unsaubere Trennung erkennt, genau wie in MQTT 3.1.1.
Warum ignoriert meine Will Message die Verzögerung?
Meist ist das Session Expiry Interval 0 oder kürzer als das Will Delay. Der Broker veröffentlicht den Will, wenn die Session endet, daher muss die Session mindestens so lange bestehen wie die Verzögerung.
Gibt es Will Delay in MQTT 3.1.1?
Nein. Es ist eine Funktion von MQTT 5. Mit MQTT 3.1.1 müssten Sie Offline-Ereignisse stattdessen in der konsumierenden Anwendung entprellen.
Löst eine saubere Trennung die Will Message aus?
Nein. Ein normales DISCONNECT verwirft den Will. In MQTT 5 kann ein Client den Will gezielt anfordern, indem er sich mit dem Reason Code 0x04 (Disconnect with Will Message) trennt.



