MQTT Last Will and Testament (LWT) ist die Funktion, mit der ein Broker für einen Client sprechen kann, der selbst nicht mehr sprechen kann. Ein Gerät hinterlegt beim Verbinden eine „Will“-Nachricht, und der Broker publiziert sie, wenn das Gerät ohne sauberes Trennen verschwindet. Am Ende dieses Artikels kennen Sie jedes Will-Feld, die genauen Bedingungen, die es auslösen, und wissen, wie Sie es selbst testen, indem Sie einen mit einem Live-Broker verbundenen Client beenden.
Warum MQTT einen Last Will braucht
MQTT ist für unzuverlässige Netzwerke konzipiert. Geräte verlieren Strom, Firmware hängt sich auf, ein SPS-Gateway in der Halle startet neu, Mobilfunkverbindungen brechen minutenlang ab. In einem reinen Publish/Subscribe-System sprechen Publisher und Subscriber nie direkt miteinander, also würde niemand bemerken, dass ein Sensor verstummt ist, bis ein Mensch auf ein veraltetes Dashboard schaut.
Der MQTT-Broker ist die einzige Instanz, die jede Verbindung sieht. LWT macht aus dieser Position eine Funktion: Der Client sagt dem Broker im Voraus „Wenn ich verschwinde, publiziere das für mich.“ Subscriber erfahren vom Ausfall dann über dieselben Topics, die sie ohnehin beobachten.
Die Felder von MQTT Last Will and Testament
Der Will wird im CONNECT-Paket gesetzt, muss also vor dem Verbinden konfiguriert werden. Während einer Session lässt er sich nicht ändern; dafür ist ein neuer Verbindungsaufbau nötig.
| Feld | Zweck | Typischer Wert |
|---|---|---|
| Will-Topic | Wohin der Broker den Will publiziert | site/line1/pump-07/status |
| Will-Payload | Nachrichteninhalt | offline oder {"state":"offline"} |
| Will-QoS | Zustellgarantie für den Will | 1 |
| Will-Retain | Ob der Will zum Retained-Wert wird | true |
| Will Delay Interval (MQTT 5) | Wartezeit in Sekunden vor dem Publizieren | 0 bis einige Sekunden |
| Will Properties (MQTT 5) | Message Expiry, Content Type, User Properties | Optional |
Die meisten Produktivsysteme nutzen QoS 1 und Retain true. Retain macht den Status erst für Clients nützlich, die sich später verbinden; ohne es erfährt ein Dashboard, das nach dem Ausfall geöffnet wird, nie, dass das Gerät down ist. Das Retained-Verhalten wird ausführlich in MQTT Retained Messages erklärt.
Wann der Broker den Will publiziert
Der Broker publiziert den Will, wenn die Netzwerkverbindung ohne DISCONNECT-Paket geschlossen wird. In der Praxis umfasst das:
- Die TCP-Verbindung wird vom Betriebssystem des Clients geschlossen oder zurückgesetzt, etwa bei einem beendeten Prozess.
- Der Keepalive-Timer läuft ab. Der Broker wartet etwa das 1,5-Fache des Keepalive-Intervalls ohne Pakete, bevor er den Client für tot erklärt.
- Der Client verletzt das Protokoll, und der Broker schließt die Verbindung.
- Ein Netzwerkfehler, den der Broker über einen I/O-Fehler erkennt.
Er publiziert den Will nicht, wenn:
- der Client ein normales DISCONNECT sendet. Der Will wird dann verworfen.
- sich der Client in MQTT 5 vor Ablauf des Will Delay Interval erneut verbindet und seine Session fortsetzt.
Die zweite Regel ist wichtig: Ein sauberes Herunterfahren erzeugt keinen Will. Wenn Sie auch beim geordneten Herunterfahren „offline“ melden wollen, publizieren Sie das selbst vor dem Trennen. MQTT 5 erlaubt einem Client außerdem, DISCONNECT mit Reason Code 0x04 (Disconnect with Will Message) zu senden, um den Broker zu bitten, den Will trotzdem zu publizieren.
LWT testen, indem Sie einen Client beenden
Am schnellsten entwickeln Sie ein Gefühl dafür, wenn Sie einen Will auslösen sehen. Wir nutzen den öffentlichen MQTT-Broker unter broker.connectmq.com mit einem eindeutigen Topic-Präfix. Er ist für Tests und Prototypen gedacht, nicht für Produktionsdaten.
Terminal 1, der Beobachter:
mosquitto_sub -h broker.connectmq.com -p 1883 -i lwt-watch-q81m \
-t 'connectmq/demo/q81m/#' -v
Terminal 2, das „Gerät“. Es registriert einen Retained Will, nutzt ein Keepalive von 10 Sekunden und bleibt abonniert, damit der Prozess weiterläuft:
mosquitto_sub -h broker.connectmq.com -p 1883 -i lwt-device-q81m -k 10 \
--will-topic connectmq/demo/q81m/device1/status \
--will-payload offline --will-qos 1 --will-retain \
-t connectmq/demo/q81m/device1/cmd
Terminal 3: Melden Sie das Gerät mit einer gespeicherten Birth-Nachricht als online:
mosquitto_pub -h broker.connectmq.com -p 1883 -i lwt-birth-q81m \
-t connectmq/demo/q81m/device1/status -m online -q 1 -r
Beenden Sie nun das Gerät abrupt. Unter Linux oder macOS:
pkill -9 -f lwt-device-q81m
Terminal 1 gibt fast sofort connectmq/demo/q81m/device1/status offline aus, weil das Betriebssystem den Socket geschlossen hat und der Broker den Abbruch ohne DISCONNECT gesehen hat. Ziehen Sie stattdessen das Netzwerkkabel oder versetzen einen Laptop in den Ruhezustand, kommt der Will erst nach Ablauf des Keepalive-Fensters an, mit -k 10 nach etwa 15 Sekunden.
Probieren Sie noch ein Experiment: Starten Sie den Geräteprozess neu und beenden Sie ihn mit Strg+C. Die Mosquitto-Tools senden bei Strg+C ein ordnungsgemäßes DISCONNECT, also wird kein Will publiziert, und der gespeicherte Status bleibt, wie er war. Genau diese Lücke schließen Sie mit einer expliziten Offline-Meldung beim Herunterfahren.
LWT in Python mit paho-mqtt
Hier ein vollständiges Geräte-Grundgerüst mit paho-mqtt 2.x. Es setzt den Will vor dem Verbinden, publiziert eine gespeicherte Birth-Nachricht in on_connect (sodass sie nach jedem Reconnect wiederholt wird) und publiziert beim geordneten Beenden „offline“:
import signal
import sys
import time
import paho.mqtt.client as mqtt
BROKER = "broker.connectmq.com"
CLIENT_ID = "lwt-py-device-q81m"
STATUS = "connectmq/demo/q81m/device2/status"
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
client.will_set(STATUS, payload="offline", qos=1, retain=True)
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code.is_failure:
print("connect failed:", reason_code)
return
client.publish(STATUS, "online", qos=1, retain=True)
print("online")
def shutdown(signum, frame):
client.publish(STATUS, "offline", qos=1, retain=True).wait_for_publish(timeout=5)
client.disconnect()
client.loop_stop()
sys.exit(0)
client.on_connect = on_connect
signal.signal(signal.SIGINT, shutdown)
signal.signal(signal.SIGTERM, shutdown)
client.connect(BROKER, 1883, keepalive=15)
client.loop_start()
while True:
time.sleep(1)
Starten Sie das Skript, beobachten Sie, wie „online“ im Beobachter-Terminal erscheint, und beenden Sie es dann mit kill -9, um den vom Broker publizierten Will zu sehen, oder drücken Sie Strg+C, um die eigene Offline-Nachricht des Skripts zu sehen.
Designtipps für zuverlässige Offline-Erkennung
Wählen Sie ein sinnvolles Keepalive. Das Keepalive bestimmt die schlechteste Erkennungszeit für stille Ausfälle. 15 bis 60 Sekunden sind für netzbetriebene Geräte üblich. Sehr kurze Werte kosten Akku und Bandbreite, sehr lange verzögern Alarme. Unser Leitfaden zum MQTT Keep Alive Interval behandelt die Abwägungen.
Kombinieren Sie LWT immer mit einer Birth-Nachricht. Der Will sagt nur „offline“. Irgendetwas muss nach dem Reconnect wieder „online“ melden, und das muss retained sein, damit es den gespeicherten Will überschreibt.
Verwenden Sie für beides dasselbe Topic und Retain-Flag. Ist der Will retained, die Birth-Nachricht aber nicht, sehen neue Subscriber für immer „offline“.
Achten Sie auf doppelte Client IDs. Teilen sich zwei Geräte eine Client ID, trennt der Broker das eine, wenn sich das andere verbindet, und sie werfen sich in einer Schleife gegenseitig hinaus. Der Status springt zwischen online und offline hin und her. Machen Sie jede Client ID eindeutig.
Erwägen Sie in MQTT 5 ein Will Delay. Eine kurze Verzögerung verhindert ein kurzes „offline“-Aufblitzen, wenn sich ein Gerät nach einer Netzwerkstörung schnell wieder verbindet. Details unter das MQTT Will Delay Interval.
Geben Sie in JSON-Payloads Kontext mit. Ein Payload wie {"state":"offline","reason":"lwt"} lässt Konsumenten einen Absturz von einem geplanten Herunterfahren unterscheiden.
Legen Sie den Status in den Unified Namespace. In Industrie-4.0-Architekturen ist der Unified Namespace (UNS) die zentrale Topic-Struktur auf dem Broker, gegliedert nach der ISA-95-Hierarchie Enterprise, Site, Area, Line und Cell. Liegt das Will-Topic direkt am Knoten der Anlage, etwa acme/werk-stuttgart/montage/linie-1/zelle-3/status, sehen MES, SCADA und OEE-Dashboards den Online-Status genau dort, wo sie auch die Maschinendaten lesen. Sparkplug B baut ebenfalls auf LWT auf: Die NDEATH-Nachricht eines Edge-Knotens wird als Will registriert. Mehr dazu unter Sparkplug B und Unified Namespace.
Last Will and Testament auf ConnectMQ
ConnectMQ unterstützt LWT sowohl bei MQTT-3.1.1- als auch bei 5.0-Verbindungen, einschließlich Retained Wills. Auf einem produktiven Broker verbinden Sie sich mit den Zugangsdaten aus dem Portal (YOUR_USERNAME, YOUR_PASSWORD, YOUR_CLIENT_ID) über TLS auf Port 8883, und der Will funktioniert genau wie in den obigen Beispielen. Da Client IDs bei ConnectMQ an ausgestellte Zugangsdaten gebunden sind, lässt sich das Hin-und-her-Springen durch doppelte IDs leichter vermeiden.
Für brokerseitige Transparenz zusätzlich zu LWT stellt ConnectMQ den Verbindungsstatus außerdem unter $SYS/broker/connection/{clientId}/state bereit – praktisch für Monitoring-Tools, die nicht davon abhängen sollen, dass jedes Gerät seinen Will korrekt konfiguriert. Wenn Sie entscheiden, wo Sie das hosten, vergleichen Sie die Optionen in unserer Übersicht zum verwalteten MQTT-Broker, und für die Protokollgrundlagen lesen Sie das vollständige MQTT-Tutorial.
Starten Sie mit ConnectMQ
Registrieren Sie sich unter app.connectmq.com und erstellen Sie einen Broker im kostenlosen Serverless-Plan, ganz ohne Kreditkarte. Richten Sie Ihre Geräte mit einem Retained Last Will und einer Birth-Nachricht darauf aus, und Sie haben vom ersten Tag an einen zuverlässigen Online-/Offline-Status.
Häufig gestellte Fragen
Wird der Last Will publiziert, wenn sich ein Client normal trennt?
Nein. Ein normales DISCONNECT weist den Broker an, den Will zu verwerfen. Publizieren Sie vor dem Trennen eine eigene Offline-Nachricht, wenn Sie eine für geplantes Herunterfahren brauchen.
Wie lange dauert es, bis der Broker den Will publiziert?
Wird der Socket geschlossen, geschieht es fast sofort. Verschwindet das Gerät still, wartet der Broker etwa das 1,5-Fache des Keepalive-Intervalls, zuzüglich eines eventuellen Will Delay Interval in MQTT 5.
Sollte die Will-Nachricht retained sein?
In der Regel ja. Ein Retained Will stellt sicher, dass Clients, die sich nach dem Ausfall verbinden, das Gerät weiterhin als offline sehen.
Kann ich den Will nach dem Verbinden ändern?
Nein. Der Will ist Teil des CONNECT-Pakets. Um ihn zu ändern, trennen Sie die Verbindung und verbinden sich mit neuen Will-Einstellungen erneut.



