MQTT-Grundlagen

MQTT Last Will and Testament (LWT): Offline-Geräte erkennen

Mit Last Will and Testament kann der Broker melden, dass ein Client sich ohne Abschied verabschiedet hat. Lernen Sie die Will-Felder, die genauen Auslöseregeln und wie Sie LWT testen, indem Sie einen Client auf einem Live-Broker beenden.

Broker, der nach dem Verbindungsabbruch eines Sensors eine Offline-Meldung publiziert, als Illustration von MQTT Last Will and Testament
Probieren Sie es auf Ihrem eigenen MQTT-Broker ausHolen Sie sich im Free-Tarif einen privaten, verwalteten MQTT-Broker und starten Sie mit fertigen Codebeispielen.
Kostenlos testen Codebeispiele Keine Kreditkarte erforderlich

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:

  1. Die TCP-Verbindung wird vom Betriebssystem des Clients geschlossen oder zurückgesetzt, etwa bei einem beendeten Prozess.
  2. 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.
  3. Der Client verletzt das Protokoll, und der Broker schließt die Verbindung.
  4. 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.

Verwandte Artikel

Wer hat MQTT erfunden? Die Geschichte von Ölpipelines bis zum IoT

MQTT wurde 1999 von Andy Stanford-Clark (IBM) und Arlen Nipper (Arcom) erfunden, um Ölpipelines per Satellit zu überwachen. Verfolgen Sie den Weg zu Open Source, OASIS, ISO und den heutigen verwalteten MQTT-Brokern in der Cloud.

8 Min. Lesezeit

Alle Artikel →

Ihr privater MQTT-Broker ist nur wenige Klicks entfernt

Konto anlegen, Broker-Zugangsdaten erhalten und das erste Gerät verbinden — ohne Server, die installiert, gepatcht oder skaliert werden müssen.