MQTT-Grundlagen

Wie funktioniert MQTT? Broker, Clients und Nachrichten erklärt

Eine Schritt-für-Schritt-Erklärung, wie MQTT funktioniert, von der TCP-Verbindung über CONNECT, SUBSCRIBE, PUBLISH und Keep Alive bis zum Disconnect, mit einem Trace, den Sie auf einem öffentlichen MQTT-Broker nachvollziehen können.

Diagramm zur Funktionsweise von MQTT: Clients senden CONNECT-, SUBSCRIBE- und PUBLISH-Pakete über einen zentralen Broker
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

Wie funktioniert MQTT? Kurz gesagt öffnen Clients eine einzige langlebige Verbindung zu einem Broker, teilen mit, welche Topics sie interessieren, und der Broker leitet jede publizierte Nachricht an die passenden Subscriber weiter. In diesem Artikel verfolgen Sie diesen Ablauf Paket für Paket, von der TCP-Verbindung über CONNECT, SUBSCRIBE, PUBLISH und Keep Alive bis zum Disconnect, und reproduzieren den gesamten Trace selbst auf einem öffentlichen MQTT-Broker.

Die drei Rollen: Publisher, Subscriber und Broker

MQTT kennt nur zwei Arten von Teilnehmern: Clients und Broker. Ein Client kann publizieren, abonnieren oder beides. Der Broker sitzt in der Mitte, empfängt jede Nachricht und entscheidet, wer sie erhält.

  • Publisher senden Nachrichten an ein Topic, eine Zeichenkette wie plant1/line2/temperature. Sie wissen nicht, wer sie empfängt, und es kümmert sie auch nicht.
  • Subscriber teilen dem Broker mit, welche Topics oder Topic-Muster sie haben möchten. Sie wissen nicht, wer sendet.
  • Der Broker authentifiziert Clients, verwaltet Abonnements und Sessions und leitet jede Nachricht an alle passenden Subscriber weiter.

Diese Entkopplung ist das Herzstück des Designs. Ein Sensor braucht nicht die IP-Adresse eines Dashboards, beide müssen bei persistenten Sessions nicht gleichzeitig online sein, und ein fünfter Konsument erfordert keine Änderung am Sensor. Mehr zur Aufgabe des Brokers finden Sie unter was ein MQTT Broker macht, und zum Muster selbst im Artikel über das MQTT-Publish/Subscribe-Modell. In Industrie-4.0-Anwendungen folgt die Topic-Hierarchie häufig der ISA-95-Anlagenstruktur und bildet so einen Unified Namespace (UNS), etwa acme/werk-stuttgart/montage/linie-1/zelle-3/temperatur; mehr dazu im Beitrag zu Sparkplug B und Unified Namespace.

Schritt 1: Eine Netzwerkverbindung öffnen

MQTT läuft über einen zuverlässigen, geordneten Bytestrom, normalerweise TCP. Der Client öffnet eine TCP-Verbindung zum Broker, auf Port 1883 für unverschlüsseltes MQTT oder 8883 für MQTT über TLS. Browser, die keine rohen TCP-Sockets öffnen können, transportieren MQTT stattdessen in einem WebSocket (bei ConnectMQ auf 8083 oder 8084 mit dem Pfad /mqtt). Bis hierhin ist noch nichts MQTT-Spezifisches passiert; das ist nur die Leitung.

Mit TLS folgt nun ein Handshake: Der Client prüft das Zertifikat des Brokers, und beide Seiten einigen sich auf Schlüssel für die Verschlüsselung. Jedes nachfolgende MQTT-Paket ist verschlüsselt.

Schritt 2: CONNECT und CONNACK

Das erste Paket des Clients muss CONNECT sein. Es enthält:

Feld Zweck
Protokollname und -stufe MQTT und 4 (3.1.1) oder 5 (5.0)
Client ID Identifiziert die Session; muss pro Verbindung eindeutig sein
Clean Session / Clean Start Neu beginnen oder eine gespeicherte Session fortsetzen
Keep Alive Maximale Sekunden zwischen Paketen des Clients
Benutzername und Passwort Optionale Zugangsdaten
Last Will Optionale Nachricht, die der Broker publiziert, wenn der Client verschwindet
Properties (MQTT 5) Session Expiry, Receive Maximum, Maximum Packet Size und mehr

Der Broker prüft all das und antwortet mit CONNACK. In MQTT 5 enthält es einen Reason Code: 0x00 für Erfolg oder einen Fehler wie falsche Zugangsdaten, nicht autorisiert oder, bei einem Broker mit Kontingenten, 0x97 Quota exceeded. Es gibt außerdem an, ob eine vorherige Session fortgesetzt wurde (Session-Present-Flag), und kann dem Client Server-Limits mitteilen. Bis ein erfolgreiches CONNACK eintrifft, darf der Client nichts anderes senden.

Schritt 3: SUBSCRIBE und SUBACK

Ein Client, der Nachrichten empfangen möchte, sendet SUBSCRIBE mit einem oder mehreren Topic-Filtern und jeweils einer gewünschten QoS. Filter können Wildcards enthalten: + passt auf genau eine Ebene und # auf alles unterhalb einer Ebene. So passt plant1/+/temperature auf plant1/line2/temperature, aber nicht auf plant1/line2/motor/temperature.

Der Broker antwortet mit SUBACK und nennt pro Filter die gewährte QoS (oder einen Fehlercode). Die gewährte QoS kann niedriger als die gewünschte sein, wenn der Broker sie begrenzt. Gibt es retained Messages auf passenden Topics, sendet der Broker sie sofort, und so erfährt ein neues Dashboard augenblicklich den aktuellen Zustand.

Schritt 4: PUBLISH und die QoS-Handshakes

Um Daten zu senden, schickt ein Client PUBLISH mit Topic-Namen, Payload (beliebige Bytes, oft JSON), QoS-Stufe und Retain-Flag. Was dann passiert, hängt von der QoS ab:

  1. QoS 0, höchstens einmal. PUBLISH, fertig. Keine Bestätigung; bricht die Verbindung im falschen Moment ab, ist die Nachricht verloren.
  2. QoS 1, mindestens einmal. Der Empfänger antwortet mit PUBACK. Bekommt der Sender es nicht, sendet er erneut mit gesetztem Duplicate-Flag, sodass der Empfänger die Nachricht eventuell zweimal sieht.
  3. QoS 2, genau einmal. Ein Austausch in vier Schritten: PUBLISH, PUBREC, PUBREL, PUBCOMP. Langsamer, aber ohne Duplikate.

Diese Handshakes finden pro Teilstrecke statt: einmal zwischen Publisher und Broker und separat zwischen Broker und jedem Subscriber. Der Broker leitet die Nachricht dann an jeden Client weiter, dessen Filter passt, und verwendet dabei die niedrigere von Publish-QoS und gewährter Abonnement-QoS. Alle Abwägungen finden Sie unter MQTT-QoS-Stufen erklärt.

Ist das Retain-Flag gesetzt, speichert der Broker die Nachricht zusätzlich als letzten bekannten Wert für dieses Topic und übergibt sie künftigen Subscribern.

Schritt 5: Keep Alive mit PINGREQ und PINGRESP

Auch im Leerlauf muss ein Client innerhalb des Keep-Alive-Intervalls beweisen, dass er noch lebt. Hat er nichts zu publizieren, sendet er PINGREQ, und der Broker antwortet mit PINGRESP. Hört der Broker etwa das Anderthalbfache des Keep-Alive-Zeitraums nichts, betrachtet er den Client als tot, schließt die Verbindung und publiziert den Last Will des Clients, falls einer gesetzt wurde. So erfahren Dashboards, dass ein Gerät offline gegangen ist, ohne dass jemand pollen muss.

Schritt 6: DISCONNECT und Sessions

Ein sauberes Beenden sendet DISCONNECT, was dem Broker mitteilt, den Last Will nicht zu publizieren. Was bestehen bleibt, hängt von den Session-Einstellungen ab: Mit Clean Start und ohne Session Expiry vergisst der Broker die Abonnements des Clients. Bei einer persistenten Session (MQTT 5 Session Expiry größer als null) behält der Broker die Abonnements und puffert Nachrichten mit QoS 1 und 2, bis der Client zurückkehrt oder die Frist abläuft.

Den Trace selbst nachvollziehen

Sie können den gesamten Ablauf auf dem kostenlosen öffentlichen MQTT-Broker unter broker.connectmq.com beobachten. Die Mosquitto-Clients geben mit -d jedes Paket aus. Wählen Sie zuerst eine eindeutige zufällige ID; hier ist es q7m3x9.

# Terminal 1: Subscriber mit Debug-Ausgabe
mosquitto_sub -h broker.connectmq.com -p 1883 -i sub-q7m3x9 -V mqttv5 -d \
  -t 'connectmq/demo/q7m3x9/#' -q 1

# Terminal 2: Publisher mit Debug-Ausgabe
mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-q7m3x9 -V mqttv5 -d \
  -t 'connectmq/demo/q7m3x9/sensor/temp' -m '{"c":21.7}' -q 1

Die Ausgabe des Subscribers sieht so aus (Details variieren je nach Version):

Client sub-q7m3x9 sending CONNECT
Client sub-q7m3x9 received CONNACK (0)
Client sub-q7m3x9 sending SUBSCRIBE (Mid: 1, Topic: connectmq/demo/q7m3x9/#, QoS: 1, Options: 0x00)
Client sub-q7m3x9 received SUBACK
Subscribed (mid: 1): 1
Client sub-q7m3x9 received PUBLISH (d0, q1, r0, m1, 'connectmq/demo/q7m3x9/sensor/temp', ... (10 bytes))
Client sub-q7m3x9 sending PUBACK (m1, rc0)
{"c":21.7}
Client sub-q7m3x9 sending PINGREQ
Client sub-q7m3x9 received PINGRESP

Und die des Publishers:

Client pub-q7m3x9 sending CONNECT
Client pub-q7m3x9 received CONNACK (0)
Client pub-q7m3x9 sending PUBLISH (d0, q1, r0, m1, 'connectmq/demo/q7m3x9/sensor/temp', ... (10 bytes))
Client pub-q7m3x9 received PUBACK (Mid: 1, RC:0)
Client pub-q7m3x9 sending DISCONNECT

Lesen Sie die Flags der PUBLISH-Zeile: d0 (kein Duplikat), q1 (QoS 1), r0 (nicht retained), m1 (Paket-ID 1). Probieren Sie -q 2, und Sie sehen PUBREC, PUBREL und PUBCOMP; ergänzen Sie -r beim Publisher, starten Sie den Subscriber neu, und die retained Message kommt direkt nach SUBACK an. Der öffentliche MQTT-Broker ist für jeden lesbar und für Tests und Prototypen gedacht, senden Sie also nur Testdaten.

Derselbe Ablauf in Python

Bibliotheken verbergen die Pakete hinter Callbacks, doch jeder davon entspricht einem der Schritte oben.

import time
import uuid

import paho.mqtt.client as mqtt

PREFIX = f"connectmq/demo/{uuid.uuid4().hex[:6]}"


def on_connect(client, userdata, flags, reason_code, properties):   # CONNACK
    print("CONNACK:", reason_code)
    client.subscribe(f"{PREFIX}/#", qos=1)                           # SUBSCRIBE


def on_subscribe(client, userdata, mid, reason_codes, properties):  # SUBACK
    print("SUBACK:", [str(rc) for rc in reason_codes])
    client.publish(f"{PREFIX}/sensor/temp", '{"c":21.7}', qos=1)     # PUBLISH


def on_publish(client, userdata, mid, reason_code, properties):     # PUBACK
    print("PUBACK for mid", mid)


def on_message(client, userdata, msg):                               # eingehendes PUBLISH
    print("Message:", msg.topic, msg.payload.decode())


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id=f"trace-{uuid.uuid4().hex[:8]}",
                     protocol=mqtt.MQTTv5)
client.on_connect = on_connect
client.on_subscribe = on_subscribe
client.on_publish = on_publish
client.on_message = on_message

client.connect("broker.connectmq.com", 1883, keepalive=30)          # TCP + CONNECT
client.loop_start()
time.sleep(5)
client.disconnect()                                                  # DISCONNECT
client.loop_stop()

Häufige Missverständnisse

  • „Der Broker speichert alle Nachrichten.“ Nur retained Messages (eine pro Topic) und gepufferte Nachrichten für persistente Sessions. MQTT ist weder Datenbank noch Log.
  • „Topics müssen zuerst angelegt werden.“ Nein, Topics existieren in dem Moment, in dem jemand publiziert oder abonniert.
  • „QoS 2 gilt Ende zu Ende.“ QoS gilt pro Teilstrecke und wird auf die Stufe des Abonnements herabgesetzt.
  • „Client IDs kann man teilen.“ Eine zweite Verbindung mit derselben ID wirft die erste hinaus.
  • „MQTT nutzt UDP.“ Standard-MQTT benötigt TCP oder einen anderen zuverlässigen Strom; MQTT-SN ist die Variante für UDP und ähnliche Netze.

Wenn Sie tiefer einsteigen möchten: Das MQTT-Tutorial baut ein komplettes Projekt, MQTT-Steuerpakete beschreibt jeden Pakettyp im Detail, und die offiziellen Spezifikationen sind unter mqtt.org veröffentlicht.

Probieren Sie MQTT auf ConnectMQ aus

Experimentieren Sie frei auf broker.connectmq.com und erstellen Sie dann unter app.connectmq.com ohne Kreditkarte einen kostenlosen Serverless Broker, wenn Sie private, authentifizierte Topics möchten. ConnectMQ ist ein Cloud-MQTT-Broker mit Unterstützung für MQTT 3.1.1 und 5.0, einem Client im Browser und einem Live-Topic-Explorer, sodass Sie die hier beschriebenen Abläufe in Echtzeit beobachten können. Wenn Sie in die Produktion gehen, läuft er als verwalteter MQTT-Broker.

Häufig gestellte Fragen

Wie funktioniert MQTT, einfach erklärt?

Geräte verbinden sich mit einem zentralen Broker, abonnieren die Topics, die sie interessieren, und publizieren Nachrichten auf Topics. Der Broker leitet jede Nachricht an alle passenden Subscriber weiter.

Verbinden sich Publisher und Subscriber direkt miteinander?

Nein. Jeder Client verbindet sich nur mit dem Broker, weshalb Geräte nie die Adressen der anderen benötigen.

Was passiert, wenn ein Subscriber offline ist, während eine Nachricht publiziert wird?

Mit einer persistenten Session und QoS 1 oder 2 puffert der Broker die Nachricht, bis der Subscriber sich wieder verbindet oder die Session abläuft. Andernfalls wird die Nachricht diesem Client nicht zugestellt, eine retained Message liefert ihm aber trotzdem den neuesten Wert.

Welchen Port nutzt MQTT?

1883 für unverschlüsseltes TCP und 8883 für TLS. WebSocket-Ports unterscheiden sich je nach Broker; ConnectMQ verwendet 8083 und 8084 mit dem Pfad /mqtt.

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.