Geräte in unzuverlässigen Netzen bekommen selten die Gelegenheit, sich zu verabschieden. Akkus sind leer, das WLAN fällt aus, Prozesse stürzen ab. Mit dem Last Will and Testament (LWT) von MQTT kann ein Client vorab eine Nachricht hinterlegen, die der Broker in seinem Namen publisht, falls der Client unerwartet verschwindet. Es ist der Standardbaustein für Präsenzerkennung und Alarmierung in MQTT-Systemen.
So funktioniert Last Will
Der Last Will wird im CONNECT-Paket festgelegt. Er besteht aus denselben Teilen wie ein normales Publish:
| Feld | Bedeutung |
|---|---|
| Will Topic | Wohin der Broker publisht, z. B. acme/sensor-17/status |
| Will Payload | Der Nachrichteninhalt, z. B. offline |
| Will QoS | 0, 1 oder 2 – siehe QoS-Stufen |
| Will Retain | Ob der Will als Retained Message gespeichert wird |
| Will Properties (MQTT 5) | Will Delay Interval, Message Expiry, Content Type, User Properties … |
Der Broker bewahrt den Will zusammen mit der Session auf und tut nichts damit, solange der Client verbunden ist. Was danach passiert, hängt davon ab, wie die Verbindung endet.
Wann wird der Will publisht?
Der Broker publisht den Will, wenn die Netzwerkverbindung ohne ein reguläres Disconnect endet, unter anderem wenn:
- der Broker einen I/O-Fehler oder Netzwerkausfall feststellt;
- der Client innerhalb der Keep-Alive-Zeit nicht kommuniziert – der Broker wartet bis zu 1,5 × dem Keep-Alive-Intervall, bevor er die Verbindung als tot betrachtet;
- der Client die TCP-/WebSocket-Verbindung schließt, ohne
DISCONNECTzu senden; - der Broker die Verbindung wegen eines Protokollfehlers schließt.
Der Will wird nicht publisht, wenn der Client ein reguläres DISCONNECT sendet; ein sauberes Herunterfahren löscht ihn. MQTT 5 kennt eine Ausnahme: Ein Client kann sich mit dem Reason Code 0x04 (Disconnect with Will Message) sauber trennen und den Will trotzdem senden lassen.
Will Delay Interval (MQTT 5)
In MQTT 3.1.1 wird der Will sofort ausgelöst. Bei Geräten, die sich nach einem kurzen Netzaussetzer schnell neu verbinden, erzeugt das Rauschen: Subscriber sehen offline und eine Sekunde später online. MQTT 5 ergänzt deshalb die Property Will Delay Interval (in Sekunden):
- Der Broker wartet die Verzögerung ab, bevor er den Will publisht.
- Verbindet sich der Client innerhalb dieser Zeit mit derselben Client-ID neu, wird der Will nicht gesendet.
- Der Will wird publisht, wenn die Verzögerung abläuft oder die Session endet – je nachdem, was zuerst eintritt. Ein Will Delay, der länger ist als das
Session Expiry Interval, wird dadurch faktisch gekappt.
const client = mqtt.connect('wss://broker.emqx.io:8084/mqtt', {
protocolVersion: 5,
clientId: 'sensor-17',
properties: { sessionExpiryInterval: 300 },
will: {
topic: 'acme/sensor-17/status',
payload: 'offline',
qos: 1,
retain: true,
properties: { willDelayInterval: 30 },
},
});Das Präsenzmuster: Online-/Offline-Status
Am häufigsten wird LWT mit Retained Messages kombiniert, sodass jeder Client jederzeit sehen kann, ob ein Gerät online ist:
- Verbinden mit einem Will: Topic
acme/sensor-17/status, Payloadoffline, QoS 1, retain = true. - Direkt nach dem CONNACK
onlinean dasselbe Topic publishen, QoS 1, retain = true. Das überschreibt ein veraltetesofflinevom letzten Mal. - Beim geordneten Herunterfahren selbst
offline(retained) publishen und dannDISCONNECTsenden. Da der Will bei einem sauberen Disconnect verworfen wird, hält genau dieses explizite Publish den Status korrekt. - Bei einem Absturz publisht der Broker den gespeicherten
offline-Will für dich.
Dashboards abonnieren dann acme/+/status und erhalten dank Retain sofort den aktuellen Status jedes Geräts.
import mqtt from 'mqtt';
const statusTopic = 'acme/sensor-17/status';
const client = mqtt.connect('wss://broker.hivemq.com:8884/mqtt', {
clientId: 'sensor-17',
keepalive: 30,
will: { topic: statusTopic, payload: 'offline', qos: 1, retain: true },
});
client.on('connect', () => {
client.publish(statusTopic, 'online', { qos: 1, retain: true });
});
process.on('SIGINT', () => {
client.publish(statusTopic, 'offline', { qos: 1, retain: true }, () => client.end());
});Häufige Stolperfallen
- Kollidierende Client-IDs. Verbindet sich ein zweiter Client mit derselben Client-ID, trennt der Broker den ersten – und publisht dessen Will. Zwei Instanzen, die um eine ID kämpfen, erzeugen einen ständig wechselnden Online-/Offline-Status.
- Bibliotheken, die sich immer sauber trennen. Manche SDKs senden beim Beenden des Prozesses ein
DISCONNECT, sodass der Will nie ausgelöst wird. Teste, indem du den Prozess killst oder das Netz kappst. - Retain vergessen. Einen nicht gespeicherten Will sehen nur Clients, die genau in diesem Moment abonniert haben.
- Autorisierung. Der Will wird mit den Berechtigungen des Clients publisht. Darf der Client nicht an das Will-Topic publishen, lehnt der Broker die Verbindung womöglich ab oder verwirft den Will stillschweigend. Siehe MQTT-Verbindungsfehler.
Einen Will über die Kommandozeile setzen
Die Mosquitto-Clients akzeptieren Will-Optionen direkt, was schnelle Experimente einfach macht. Starte in einem Terminal einen Subscriber, verbinde dann einen zweiten Client mit einem Will und beende ihn mit Ctrl+C oder durch Schließen des Terminals:
# terminal 1 — watch the status topic
mosquitto_sub -h test.mosquitto.org -t 'testmqtt/lwt-demo/#' -v
# terminal 2 — connect with a retained will and a 10 s keep-alive
mosquitto_sub -h test.mosquitto.org -t 'testmqtt/lwt-demo/cmd' -k 10 \
--will-topic 'testmqtt/lwt-demo/status' --will-payload 'offline' \
--will-qos 1 --will-retainJe nachdem, wie der Prozess endet, kommt der Client noch dazu, DISCONNECT zu senden – oder eben nicht. Am zuverlässigsten siehst du den Will, wenn du das Netz trennst (zum Beispiel WLAN deaktivierst) und wartest, bis der Keep-Alive abläuft – genau der Fehlerfall, für den LWT gemacht ist.
So testest du Last Will
- Abonniere in einem Tab des Online-MQTT-Clients
testmqtt/lwt-demo/#. - Verbinde dich in einem zweiten Tab mit einem Will auf
testmqtt/lwt-demo/statusund einem kurzen Keep-Alive. - Schließe den zweiten Tab, ohne die Verbindung zu trennen. Innerhalb des Keep-Alive-Fensters empfängt der erste Tab den Will.
Im Online-MQTT-Client ausprobieren
Häufig gestellte Fragen
Warum wird mein MQTT Last Will nicht gesendet?
Der Broker publisht den Will nur, wenn sich ein Client unsauber trennt. Sendet deine Client-Bibliothek beim Schließen ein DISCONNECT-Paket, wird der Will verworfen. Prüfe außerdem den Keep-Alive: Der Broker wartet unter Umständen bis zum 1,5-Fachen des Keep-Alive-Intervalls, bevor er eine tote Verbindung bemerkt.
Kann ich den Last Will nach dem Verbinden ändern?
Nein. Der Will ist Teil des CONNECT-Pakets und kann während der Session nicht geändert werden. Um ihn zu ändern, trenne die Verbindung und verbinde dich mit einem neuen Will erneut.
Sollte die Last-Will-Nachricht retained sein?
Für Präsenz- und Status-Topics ja. Ein als Retained gespeicherter Offline-Will sorgt dafür, dass später abonnierende Clients das Gerät weiterhin als offline sehen – statt gar nichts oder eine alte Online-Nachricht.