IoT-Tutorials

Paho MQTT Python Tutorial: Publish und Subscribe in 10 Minuten

Installieren Sie paho-mqtt 2.x, bauen Sie einen funktionierenden Publisher und Subscriber gegen broker.connectmq.com, lernen Sie Netzwerkschleife, QoS, Retained Messages und Last Will kennen und wechseln Sie dann auf einen privaten Broker mit Zugangsdaten und TLS.

Python-Terminal mit einem Paho-MQTT-Python-Publisher und -Subscriber, die Sensornachrichten austauschen
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

Paho MQTT Python ist der Standardweg, um aus Python heraus MQTT zu sprechen – ob Sie einen Sensor auf dem Raspberry Pi skripten, Maschinendaten auf einem Edge-Gateway in der Fertigung weiterleiten, einen Backend-Dienst bauen oder ein Gerät testen. In diesem Tutorial installieren Sie paho-mqtt 2.x, schreiben einen Subscriber und einen Publisher, die über broker.connectmq.com kommunizieren, und verstehen die Netzwerkschleife gut genug, um die üblichen Fallen zu vermeiden. Zum Schluss stellen Sie denselben Code auf einen privaten Broker mit Zugangsdaten und TLS um.

Was Sie brauchen

  • Python 3.8 oder neuer (python --version)
  • Ein Terminal mit ausgehendem Zugriff auf Port 1883 bzw. 8883 für TLS
  • Zehn Minuten

Für den ersten Teil brauchen Sie kein Konto. Der kostenlose öffentliche MQTT-Broker unter broker.connectmq.com ist für Tests und Prototypen gedacht und akzeptiert anonyme Verbindungen mit jeder nicht leeren, eindeutigen Client ID. Sein öffentlicher Bereich ist für alle lesbar, verwenden Sie also ein zufälliges Topic-Präfix und senden Sie dort niemals echte Daten.

paho-mqtt installieren

Erstellen Sie eine virtuelle Umgebung und installieren Sie die Bibliothek:

python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install "paho-mqtt>=2.0"
python -c "import paho.mqtt; print(paho.mqtt.__version__)"

Sie sollten eine 2.x-Version sehen. Version 2.0 hat geändert, wie der Client erzeugt und wie Callbacks aufgerufen werden. Viele Tutorials im Netz zeigen noch den 1.x-Stil, der inzwischen fehlschlägt oder Deprecation-Warnungen ausgibt. Alles hier verwendet den aktuellen Stil; migrieren Sie bestehenden Code, lesen Sie den Leitfaden zur Callback-API-Version von paho-mqtt 2.0.

Schritt 1: Ein Subscriber

Speichern Sie dies als subscriber.py. Ersetzen Sie k7f3q2 durch eine eigene Zufallszeichenfolge:

import uuid

import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
PORT = 1883
TOPIC = "connectmq/demo/k7f3q2/#"


def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print(f"Connection failed: {reason_code}")
        return
    print(f"Connected to {BROKER}")
    # Hier abonnieren, damit die Subscription nach jedem Reconnect wiederhergestellt wird.
    client.subscribe(TOPIC, qos=1)


def on_subscribe(client, userdata, mid, reason_code_list, properties):
    for rc in reason_code_list:
        if rc.is_failure:
            print(f"Subscription rejected: {rc}")
        else:
            print(f"Subscribed with QoS {rc.value}")


def on_message(client, userdata, msg):
    retained = " (retained)" if msg.retain else ""
    print(f"{msg.topic}{retained}: {msg.payload.decode('utf-8', errors='replace')}")


def on_disconnect(client, userdata, disconnect_flags, reason_code, properties):
    print(f"Disconnected: {reason_code}")


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

client.connect(BROKER, PORT, keepalive=60)
client.loop_forever()

Starten Sie ihn mit python subscriber.py. Er gibt „Connected" und „Subscribed with QoS 1" aus und wartet dann.

Schritt 2: Ein Publisher

Speichern Sie in einem zweiten Terminal Folgendes als publisher.py:

import json
import random
import time
import uuid

import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
PORT = 1883
PREFIX = "connectmq/demo/k7f3q2"

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"pub-{uuid.uuid4().hex[:8]}")

# Last Will: wird vom Broker publiziert, wenn dieser Client ohne Disconnect verschwindet.
client.will_set(f"{PREFIX}/status/publisher", payload="offline", qos=1, retain=True)

client.connect(BROKER, PORT, keepalive=60)
client.loop_start()  # Netzwerkschleife in einem Hintergrund-Thread

# Retained Status: neue Subscriber erhalten ihn sofort.
client.publish(f"{PREFIX}/status/publisher", "online", qos=1, retain=True)

try:
    for i in range(10):
        payload = json.dumps({"seq": i, "temperature": round(random.uniform(20, 25), 2)})
        info = client.publish(f"{PREFIX}/sensors/room1", payload, qos=1)
        info.wait_for_publish(timeout=5)
        print(f"Sent #{i} (mid={info.mid}, published={info.is_published()})")
        time.sleep(1)
finally:
    client.publish(f"{PREFIX}/status/publisher", "offline", qos=1, retain=True).wait_for_publish(5)
    client.disconnect()
    client.loop_stop()

Starten Sie python publisher.py. Der Subscriber gibt die Statusnachricht und zehn Sensorwerte aus, einen pro Sekunde.

Die Netzwerkschleife von Paho MQTT Python verstehen

Die Netzwerkschleife ist der Teil von paho, der vom Socket liest und darauf schreibt, Keepalive-Pings sendet und Ihre Callbacks aufruft. Ohne sie passiert nichts. Sie haben drei Möglichkeiten, sie zu betreiben:

Methode Blockiert? Verwenden, wenn
loop_forever() Ja, bis disconnect() Das Skript nur auf Nachrichten reagiert, etwa ein Subscriber oder Logger
loop_start() / loop_stop() Nein, läuft in einem Hintergrund-Thread Ihr Haupt-Thread andere Arbeit erledigt, etwa Sensoren ausliest
loop(timeout) Eine Iteration pro Aufruf Sie in Ihre eigene Event Loop integrieren

Der häufigste Anfängerfehler: publish() aufrufen, ohne dass eine Schleife läuft, und sich wundern, warum nichts ankommt oder QoS-1-Nachrichten nie bestätigt werden. Ein weiterer: vergessen, dass Callbacks bei loop_start() im Thread der Schleife laufen. Greift ein Callback auf Daten zu, die auch Ihr Haupt-Thread nutzt, schützen Sie sie mit einem Lock oder einer queue.Queue.

loop_forever() und loop_start() verbinden sich nach einem Verbindungsabbruch beide automatisch neu. Deshalb abonniert der Subscriber in on_connect: Bei einer Clean Session gehen Subscriptions beim Reconnect verloren und müssen neu angelegt werden. Der Leitfaden zu Reconnects mit paho-mqtt geht tiefer auf Backoff und Offline-Pufferung ein.

QoS, Retained Messages und Last Will in der Praxis

Der Publisher hat drei MQTT-Features genutzt, die es zu verstehen lohnt:

QoS 1 bedeutet, dass der Broker jede Nachricht bestätigt und paho sie erneut sendet, wenn die Bestätigung ausbleibt. wait_for_publish() blockiert bis zu dieser Bestätigung – praktisch in Skripten, die direkt nach dem Publizieren beendet werden. QoS 0 ist Fire-and-Forget und etwas günstiger; QoS 2 garantiert Exactly-Once-Zustellung auf Kosten eines zusätzlichen Roundtrips. Unser Artikel MQTT-QoS-Stufen erklärt vergleicht sie im Detail.

Retained Messages werden vom Broker gespeichert, eine pro Topic, und sofort an jeden gesendet, der später abonniert. Sie sind ideal für Zustände wie „online" oder die aktuelle Konfiguration eines Geräts. Starten Sie den Subscriber neu, und Sie sehen, dass er den retained Status sofort erhält, markiert mit „(retained)".

Last Will wird beim Verbindungsaufbau registriert. Stürzt der Publisher ab oder verliert er sein Netzwerk, publiziert der Broker nach Ablauf des Keepalive „offline" in seinem Namen. Drücken Sie während der Schleife Strg+C, sehen Sie das saubere „offline" aus dem finally-Block; beenden Sie den Prozess stattdessen mit kill -9, sendet der Broker den Will.

Mit Kommandozeilenwerkzeugen testen

Sie können Ihren Python-Code von der anderen Seite mit den Mosquitto-Clients prüfen:

mosquitto_sub -h broker.connectmq.com -p 1883 -i cli-k7f3q2 -t 'connectmq/demo/k7f3q2/#' -v

Das ConnectMQ-Portal bietet dieselbe Ansicht, ohne etwas zu installieren: Sein MQTT-Client im Browser und der Live-Topic-Explorer zeigen jedes Topic unter Ihrem Präfix, sobald Nachrichten eintreffen – nützlich beim Debuggen auf einem Rechner, auf dem Sie Mosquitto nicht installieren können. Beachten Sie, dass das Portal mit Ihrem privaten Broker arbeitet, während der CLI-Befehl oben den öffentlichen Broker anspricht.

Empfängt die CLI Ihre Nachrichten, Ihr Python-Subscriber aber nicht, liegt das Problem in Ihrem Subscriber-Code; empfängt keiner von beiden etwas, prüfen Sie den Publisher oder das Netzwerk.

Häufige Fehler und ihre Lösung

  1. ValueError: Unsupported callback API version oder ein TypeError zu callback_api_version: Sie verwenden die Erzeugung im 1.x-Stil mit paho-mqtt 2.x. Übergeben Sie mqtt.CallbackAPIVersion.VERSION2 als erstes Argument.
  2. TypeError: on_connect() takes 4 positional arguments but 5 were given: Ihr Callback hat die alte Signatur. Verwenden Sie die oben gezeigten Signaturen der Version 2.
  3. ConnectionRefusedError oder Timeouts: Port 1883 ist in Ihrem Netzwerk blockiert. Probieren Sie TLS auf 8883.
  4. Verbunden und dann in einer Schleife getrennt: Ein anderer Client verwendet dieselbe Client ID. Erzeugen Sie eine eindeutige, wie es die Beispiele tun.
  5. Nichts empfangen: Prüfen Sie, ob die Topics exakt übereinstimmen, einschließlich Groß- und Kleinschreibung und Präfix, und ob eine Schleife läuft.
  6. Nachrichten auf dem öffentlichen Broker verworfen: Er erlaubt 10 Nachrichten pro Sekunde und Client sowie 64 KB pro Nachricht. Verlangsamen Sie oder bündeln Sie Messwerte.

Umstieg auf einen privaten Broker mit Zugangsdaten und TLS

Für echte Daten erstellen Sie Ihren eigenen Broker. Registrieren Sie sich unter app.connectmq.com, wählen Sie den kostenlosen Serverless-Plan, erstellen Sie einen Broker und kopieren Sie den generierten Benutzernamen, das Passwort und die Client ID. Ändern Sie dann den Verbindungscode:

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set()  # nutzt den CA-Speicher des Systems und prüft den Hostnamen
client.connect("broker.connectmq.com", 8883, keepalive=60)

Verwenden Sie den Hostnamen, der im Portal für Ihren Broker angezeigt wird. ConnectMQ-Broker nutzen ein Let's-Encrypt-Zertifikat, dem das Standard-CA-Bundle der meisten Systeme bereits vertraut. Stoßen Sie auf Zertifikatsfehler, führt der Leitfaden zu Python, MQTT und TLS durch jeden einzelnen. Halten Sie Zugangsdaten in Umgebungsvariablen statt in Quelldateien.

Wie es weitergeht

Sobald Publish und Subscribe funktionieren, bauen diese Leitfäden auf demselben Client auf:

Die offizielle Dokumentation von Eclipse Paho für Python ist die Referenz für jede Methode und Option.

Starten Sie mit ConnectMQ

ConnectMQ ist ein verwalteter MQTT-Broker, der MQTT 3.1.1 und 5.0 über TCP, TLS und WebSocket unterstützt, mit einem Portal inklusive MQTT-Client im Browser und Live-Topic-Explorer, um zu prüfen, was Ihr Python-Code publiziert. Experimentieren Sie auf dem öffentlichen Broker und betreiben Sie Produktionsverkehr dann auf Ihrem eigenen Cloud-MQTT-Broker. Erstellen Sie ein kostenloses Konto im Serverless-Plan, ohne Kreditkarte.

Häufig gestellte Fragen

Welche Version von paho-mqtt sollte ich verwenden?

Verwenden Sie das aktuelle 2.x-Release. Es verlangt beim Erzeugen des Clients ein Argument callback_api_version, und Callbacks der Version 2 sind die empfohlene Wahl für neuen Code.

Was ist der Unterschied zwischen loop_start und loop_forever?

loop_forever() blockiert den aufrufenden Thread und betreibt die Netzwerkschleife, bis Sie die Verbindung trennen. loop_start() betreibt dieselbe Schleife in einem Hintergrund-Thread, sodass Ihr Hauptcode weiterläuft.

Unterstützt Paho MQTT Python MQTT 5?

Ja. Übergeben Sie beim Erzeugen des Clients protocol=mqtt.MQTTv5, um MQTT-5-Features wie Properties, Reason Codes und Session Expiry zu nutzen.

Brauche ich ein Konto, um paho-mqtt mit ConnectMQ auszuprobieren?

Nein. broker.connectmq.com akzeptiert zum Testen anonyme Clients auf Port 1883. Erstellen Sie ein kostenloses Konto, sobald Sie einen privaten Broker mit Zugangsdaten brauchen.

Verwandte Artikel

Die besten MQTT-CLI-Tools zum Testen, Skripten und Debuggen

Ein praxisnaher Vergleich von mosquitto_pub/sub, MQTTX CLI, HiveMQ MQTT CLI, der MQTT.js-CLI, curl und mqttui – mit demselben Test gegen broker.connectmq.com, damit Sie das richtige Tool zum Skripten und Debuggen wählen.

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.