Tutoriels IoT

Tutoriel Paho MQTT Python : publier et s'abonner en 10 minutes

Installez paho-mqtt 2.x, construisez un publisher et un subscriber fonctionnels avec broker.connectmq.com, maîtrisez la boucle réseau, la QoS, les retained messages et le Last Will, puis passez à un broker privé avec identifiants et TLS.

Terminal Python exécutant un publisher et un subscriber Paho MQTT qui échangent des messages de capteurs
Essayez-le sur votre propre broker MQTTObtenez un broker MQTT privé et managé avec l’offre Free et partez d’exemples de code prêts à l’emploi.
Essayer gratuitement Exemples de code Aucune carte bancaire requise

Paho MQTT est la manière standard de parler MQTT en Python, que vous scriptiez un capteur sur Raspberry Pi, construisiez un service backend ou testiez un appareil. Dans ce tutoriel, vous allez installer paho-mqtt 2.x, écrire un subscriber et un publisher qui communiquent via broker.connectmq.com, et comprendre suffisamment la boucle réseau pour éviter les pièges habituels. Pour finir, vous ferez passer le même code sur un broker privé avec identifiants et TLS.

Ce dont vous avez besoin

  • Python 3.8 ou plus récent (python --version)
  • Un terminal disposant d'un accès sortant au port 1883, ou 8883 pour TLS
  • Dix minutes

Aucun compte n'est nécessaire pour la première partie. Le serveur MQTT public gratuit broker.connectmq.com accepte les connexions anonymes avec n'importe quel client ID unique et non vide. Son espace public est lisible par tout le monde : utilisez un préfixe de topic aléatoire et n'y envoyez jamais de données réelles.

Installer paho-mqtt

Créez un environnement virtuel et installez la bibliothèque :

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__)"

Vous devriez voir une version 2.x. La version 2.0 a changé la manière de construire le client et d'appeler les callbacks. De nombreux tutoriels en ligne montrent encore le style 1.x, qui échoue désormais ou affiche des avertissements de dépréciation. Tout ce qui suit utilise le style actuel ; si vous migrez du code existant, consultez le guide de la version de l'API de callbacks de paho-mqtt 2.0.

Étape 1 : un subscriber

Enregistrez ceci sous subscriber.py. Remplacez k7f3q2 par votre propre chaîne aléatoire :

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}")
    # S'abonner ici pour que l'abonnement soit rétabli après chaque reconnexion.
    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()

Lancez-le avec python subscriber.py. Il affiche « Connected » et « Subscribed with QoS 1 », puis attend.

Étape 2 : un publisher

Dans un second terminal, enregistrez ceci sous 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 : publié par le broker si ce client disparaît sans se déconnecter.
client.will_set(f"{PREFIX}/status/publisher", payload="offline", qos=1, retain=True)

client.connect(BROKER, PORT, keepalive=60)
client.loop_start()  # boucle réseau dans un thread en arrière-plan

# Statut retained : les nouveaux abonnés le reçoivent immédiatement.
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()

Lancez python publisher.py. Le subscriber affiche le message de statut et dix mesures de capteur, une par seconde.

Comprendre la boucle réseau de Paho MQTT en Python

La boucle réseau est la partie de paho qui lit et écrit sur le socket, envoie les pings de keepalive et appelle vos callbacks. Sans elle, rien ne se passe. Vous avez trois façons de la faire tourner :

Méthode Bloquante ? À utiliser quand
loop_forever() Oui, jusqu'à disconnect() Le script ne fait que réagir aux messages, comme un subscriber ou un logger
loop_start() / loop_stop() Non, elle tourne dans un thread en arrière-plan Votre thread principal fait autre chose, comme lire des capteurs
loop(timeout) Une itération par appel Vous l'intégrez à votre propre boucle d'événements

Le bug de débutant le plus courant consiste à appeler publish() sans qu'aucune boucle ne tourne, puis à se demander pourquoi rien n'arrive, ou pourquoi les messages QoS 1 ne sont jamais acquittés. Un autre consiste à oublier que les callbacks s'exécutent sur le thread de la boucle quand vous utilisez loop_start() ; si un callback touche des données que votre thread principal utilise aussi, protégez-les avec un verrou ou une queue.Queue.

loop_forever() et loop_start() se reconnectent tous deux automatiquement après une coupure. C'est pourquoi le subscriber s'abonne dans on_connect : avec une clean session, les abonnements sont perdus à la reconnexion et doivent être refaits. Le guide de reconnexion paho-mqtt approfondit le backoff et la mise en tampon hors ligne.

QoS, retained messages et Last Will en pratique

Le publisher a utilisé trois fonctionnalités MQTT qu'il vaut la peine de comprendre :

La QoS 1 signifie que le broker accuse réception de chaque message, et que paho le renvoie si l'accusé n'arrive pas. wait_for_publish() bloque jusqu'à cet accusé, ce qui est pratique dans les scripts qui se terminent juste après avoir publié. La QoS 0 fonctionne en « fire-and-forget » et coûte un peu moins cher ; la QoS 2 garantit une livraison exactement une fois au prix d'un aller-retour supplémentaire. Notre article les niveaux de QoS MQTT expliqués les compare en détail.

Les retained messages sont conservés par le broker, un par topic, et envoyés immédiatement à quiconque s'abonne plus tard. Ils sont idéaux pour un état comme « online » ou la configuration actuelle d'un appareil. Redémarrez le subscriber et constatez qu'il reçoit tout de suite le statut retained, marqué « (retained) ».

Le Last Will est enregistré au moment de la connexion. Si le publisher plante ou perd son réseau, le broker publie « offline » à sa place après l'expiration du keepalive. Appuyez sur Ctrl+C pendant la boucle et vous verrez le « offline » propre du bloc finally ; tuez plutôt le processus avec kill -9 et c'est le broker qui envoie le testament.

Tester avec les outils en ligne de commande

Vous pouvez vérifier votre code Python depuis l'autre côté avec les clients Mosquitto :

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

Le portail ConnectMQ offre la même vue sans rien installer : son client MQTT intégré au navigateur et son explorateur de topics en direct montrent chaque topic sous votre préfixe à mesure que les messages arrivent, ce qui est utile pour déboguer sur une machine où vous ne pouvez pas installer Mosquitto. Gardez à l'esprit que le portail fonctionne avec votre broker privé, tandis que la commande CLI ci-dessus cible le serveur MQTT public gratuit.

Si la CLI reçoit vos messages mais pas votre subscriber Python, le problème se situe dans le code du subscriber ; si aucun des deux ne les reçoit, examinez le publisher ou le réseau.

Erreurs courantes et comment les corriger

  1. ValueError: Unsupported callback API version ou un TypeError concernant callback_api_version : vous utilisez une construction de style 1.x avec paho-mqtt 2.x. Passez mqtt.CallbackAPIVersion.VERSION2 comme premier argument.
  2. TypeError: on_connect() takes 4 positional arguments but 5 were given : votre callback a l'ancienne signature. Utilisez les signatures de la version 2 présentées ci-dessus.
  3. ConnectionRefusedError ou délais d'expiration : le port 1883 est bloqué sur votre réseau. Essayez TLS sur le port 8883.
  4. Connexion, puis déconnexion en boucle : un autre client utilise le même client ID. Générez-en un unique, comme le font les exemples.
  5. Rien n'est reçu : vérifiez que les topics correspondent exactement, casse et préfixe compris, et qu'une boucle tourne.
  6. Messages perdus sur le serveur public : il autorise 10 messages par seconde et par client et 64 Ko par message. Ralentissez ou regroupez les mesures.

Passer à un broker privé avec identifiants et TLS

Pour des données réelles, créez votre propre broker. Inscrivez-vous sur app.connectmq.com, choisissez l'offre Serverless gratuite, créez un broker et copiez le nom d'utilisateur, le mot de passe et le client ID générés. Modifiez ensuite le code de connexion :

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set()  # utilise le magasin de CA du système et vérifie le nom d'hôte
client.connect("broker.connectmq.com", 8883, keepalive=60)

Utilisez le nom d'hôte indiqué pour votre broker dans le portail. Les brokers ConnectMQ utilisent un certificat Let's Encrypt, que le bundle de CA par défaut de la plupart des systèmes reconnaît déjà. Si vous rencontrez des erreurs de certificat, le guide Python MQTT TLS les passe en revue une par une. Conservez les identifiants dans des variables d'environnement plutôt que dans les fichiers source.

Pour aller plus loin

Une fois la publication et l'abonnement opérationnels, ces guides s'appuient sur le même client :

La documentation officielle d'Eclipse Paho Python est la référence pour chaque méthode et option.

Démarrer avec ConnectMQ

ConnectMQ est un broker MQTT managé qui prend en charge MQTT 3.1.1 et 5.0 en TCP, TLS et WebSocket, avec un portail qui comprend un client MQTT intégré au navigateur et un explorateur de topics en direct pour vérifier ce que publie votre code Python. Expérimentez sur le serveur MQTT public gratuit, puis faites passer le trafic de production sur votre propre broker MQTT cloud. Créez un compte gratuit avec l'offre Serverless, sans carte bancaire.

Questions fréquentes

Quelle version de paho-mqtt utiliser ?

Utilisez la version 2.x actuelle. Elle exige un argument callback_api_version à la création du client, et les callbacks de la version 2 sont le choix recommandé pour le nouveau code.

Quelle est la différence entre loop_start et loop_forever ?

loop_forever() bloque le thread appelant et fait tourner la boucle réseau jusqu'à la déconnexion. loop_start() fait tourner la même boucle dans un thread en arrière-plan pour que votre code principal continue de s'exécuter.

Paho MQTT en Python prend-il en charge MQTT 5 ?

Oui. Passez protocol=mqtt.MQTTv5 à la création du client pour utiliser les fonctionnalités de MQTT 5 comme les properties, les reason codes et l'expiration de session.

Faut-il un compte pour essayer paho-mqtt avec ConnectMQ ?

Non. broker.connectmq.com accepte les clients anonymes sur le port 1883 pour les tests. Créez un compte gratuit quand vous avez besoin d'un broker privé avec identifiants.

Articles liés

Les meilleurs outils CLI MQTT pour tester, scripter et déboguer

Un comparatif pratique de mosquitto_pub/sub, MQTTX CLI, HiveMQ MQTT CLI, la CLI MQTT.js, curl et mqttui, avec le même test exécuté sur le serveur MQTT public gratuit broker.connectmq.com pour choisir le bon outil pour le scripting et le débogage.

9 min de lecture

Tous les articles →

Votre broker MQTT privé, à quelques clics

Créez un compte, récupérez les identifiants de votre broker et connectez votre premier appareil — aucun serveur à installer, mettre à jour ou dimensionner.