Choisir parmi les bibliothèques client MQTT est la première vraie décision d'ingénierie de tout projet MQTT, et un mauvais choix se paie plus tard sous forme de bugs de reconnexion, de fonctionnalités MQTT 5 manquantes ou de boucle d'événements bloquée. Ce guide compare les options maintenues pour Python, JavaScript, Go, Java, C#, Rust, C, les microcontrôleurs et le mobile, et vous donne pour chacune un extrait minimal qui se connecte au serveur MQTT public gratuit broker.connectmq.com. À la fin, vous saurez quelle bibliothèque convient à votre stack et quoi vérifier avant de vous engager.
Ce que fait réellement une bibliothèque client MQTT
Une bibliothèque client MQTT masque le protocole binaire derrière quelques appels : connect, subscribe, publish, disconnect. En coulisses, elle en fait bien plus, et c'est sur ces tâches cachées que les bibliothèques se distinguent :
- Encodage et décodage des paquets pour MQTT 3.1.1 et, dans les meilleures bibliothèques, les propriétés MQTT 5.0 comme les reason codes, l'expiration des messages et les user properties.
- Pings de keep-alive pour que le broker sache que la connexion est saine.
- Machines à états QoS qui stockent les messages QoS 1 et QoS 2 en transit et les renvoient après une reconnexion.
- Logique de reconnexion avec backoff, plus le réabonnement lorsque la session n'a pas été conservée.
- Gestion des transports pour TCP, TLS et WebSocket.
- Intégration du threading ou de l'asynchrone avec votre runtime : thread en arrière-plan, boucle d'événements, goroutines ou callbacks.
Une bibliothèque qui encode correctement le protocole mais gère mal les reconnexions réussira toutes les démos et échouera sur le terrain. Gardez cela en tête en lisant la comparaison ci-dessous. Si le côté broker reste flou, lisez d'abord ce que fait un broker MQTT ; chaque bibliothèque présentée ici n'est qu'un client de ce broker.
Comment évaluer les bibliothèques client MQTT
Utilisez cette checklist avant d'adopter une bibliothèque, quel que soit le langage :
- Maintenance. Regardez les versions récentes et la façon dont les issues sont traitées. MQTT lui-même est stable, mais les piles TLS, les runtimes et les plateformes évoluent sans cesse.
- Version du protocole. Avez-vous besoin de MQTT 5 ? Les abonnements partagés, l'expiration des messages, le request/response et les reason codes détaillés n'existent que là.
- Transports. Les navigateurs ont besoin de WebSocket ; les réseaux d'entreprise verrouillés exigent souvent du WSS sur des ports de type 443 ; les appareils préfèrent généralement TLS sur 8883.
- Modèle de concurrence. Callbacks, threads ou async/await. Choisissez ce qui correspond au reste de votre code, pas ce qui paraît le plus court dans un README.
- Reconnexion et mise en tampon hors ligne. Se reconnecte-t-elle automatiquement ? Met-elle les publications en file d'attente hors ligne, et cette file est-elle bornée ?
- Persistance des messages en transit. En mémoire uniquement, ou sur fichier ? Cela compte pour les QoS 1 et 2 à travers les redémarrages de processus.
- Empreinte. Sur les microcontrôleurs, la RAM et la flash décident de tout ; sur les serveurs, elles comptent rarement.
- Licence. La plupart des bibliothèques populaires utilisent EPL/EDL, MIT ou Apache 2.0, mais vérifiez avant de livrer un produit commercial.
Les bibliothèques client MQTT en un coup d'œil
| Langage / plateforme | Bibliothèque | MQTT 5 | Modèle | Idéale pour |
|---|---|---|---|---|
| Python | paho-mqtt 2.x | Oui | Thread en arrière-plan ou boucle manuelle | Scripts, passerelles, Raspberry Pi |
| Python | aiomqtt | Oui | asyncio | Services asynchrones, backends FastAPI |
| JavaScript / TypeScript | MQTT.js 5.x | Oui | Event emitter, promesses | Node.js et navigateurs (WebSocket) |
| Go | Eclipse Paho Go (paho.mqtt.golang) | Non (3.1.1) | Tokens, goroutines | Services 3.1.1 éprouvés |
| Go | Eclipse Paho paho.golang | Oui | Basé sur les contextes | Nouveaux services MQTT 5 |
| Java / Kotlin | Eclipse Paho Java (mqttv3, mqttv5) | Oui (paquet v5) | Clients synchrones et asynchrones | Backends JVM, Android |
| Java / Kotlin | HiveMQ MQTT Client | Oui | Bloquant, asynchrone, réactif | Stacks JVM réactives |
| C# / .NET | MQTTnet | Oui | async/await | ASP.NET Core, MAUI, Unity |
| Rust | rumqttc | Oui | Asynchrone (tokio) ou synchrone | Services edge, passerelles |
| C | Eclipse Paho C, libmosquitto | Oui | Synchrone et asynchrone | Appareils Linux, applications natives |
| Arduino / ESP32 | PubSubClient, AsyncMqttClient | Non (3.1.1) | Boucle / callbacks asynchrones | Microcontrôleurs |
| ESP-IDF | esp-mqtt | Oui | Gestionnaire d'événements | Firmware ESP32 de production |
| Swift | CocoaMQTT | Oui | Delegate / closures | Applications iOS et macOS |
| Dart / Flutter | mqtt_client | Non (3.1.1) | Streams | Mobile multiplateforme |
Le tableau reflète les capacités documentées des bibliothèques au moment de la rédaction. Vérifiez toujours les notes de version actuelles du projet, car la prise en charge de MQTT 5 en particulier arrive par étapes. La page du projet Eclipse Paho sur eclipse.dev/paho est un bon point de départ pour la famille Paho.
Python : paho-mqtt et aiomqtt
paho-mqtt est le choix Python par défaut et fonctionne presque partout, d'un Raspberry Pi à un conteneur. La version 2.x a introduit un changement incompatible : vous devez passer une version d'API de callbacks, et les callbacks v2 reçoivent des reason codes et des propriétés. La plupart des signalements du type « ça ne marche pas » viennent d'exemples 1.x copiés dans une installation 2.x, un cas détaillé dans le correctif CallbackAPIVersion de paho-mqtt 2.0.
import uuid
import paho.mqtt.client as mqtt
TOPIC = "connectmq/demo/k3x8p1/libs/python"
def on_connect(client, userdata, flags, reason_code, properties):
print("Connected:", reason_code)
client.subscribe(TOPIC, qos=1)
client.publish(TOPIC, "hello from paho-mqtt", qos=1)
def on_message(client, userdata, msg):
print(msg.topic, msg.payload.decode())
client = mqtt.Client(
mqtt.CallbackAPIVersion.VERSION2,
client_id=f"libs-py-{uuid.uuid4().hex[:8]}",
protocol=mqtt.MQTTv5,
)
client.on_connect = on_connect
client.on_message = on_message
client.tls_set()
client.connect("broker.connectmq.com", 8883, keepalive=30)
client.loop_forever()
aiomqtt enveloppe paho dans une API asyncio idiomatique avec async with et async for. Si votre service exécute déjà une boucle d'événements, utilisez-la plutôt que de mélanger threads et coroutines. Les guides complets se trouvent dans notre tutoriel paho-mqtt Python et le guide aiomqtt asyncio.
JavaScript et TypeScript : MQTT.js
MQTT.js est la bibliothèque de référence pour Node.js et le navigateur, embarque les types TypeScript et prend en charge MQTT 5. Sous Node.js, elle se connecte en TCP ou TLS ; dans le navigateur, elle utilise WebSocket : seul le schéma d'URL change.
import mqtt from "mqtt";
const clientId = "libs-js-" + Math.random().toString(16).slice(2, 10);
const topic = "connectmq/demo/k3x8p1/libs/javascript";
// Node.js : mqtts://broker.connectmq.com:8883
// Navigateur : wss://broker.connectmq.com:8084/mqtt
const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
clientId,
protocolVersion: 5,
});
client.on("connect", async () => {
await client.subscribeAsync(topic, { qos: 1 });
await client.publishAsync(topic, "hello from MQTT.js", { qos: 1 });
});
client.on("message", (t, payload) => console.log(t, payload.toString()));
client.on("error", (err) => console.error(err.message));
MQTT.js se reconnecte automatiquement par défaut (reconnectPeriod contrôle le délai). Dans le navigateur, rappelez-vous qu'une page HTTPS ne peut ouvrir que des connexions wss://. Les patterns propres à chaque framework sont présentés dans MQTT.js avec Node.js et MQTT dans le navigateur avec JavaScript.
Go : Eclipse Paho
Go dispose de deux projets Eclipse. paho.mqtt.golang est le client MQTT 3.1.1 bien établi, utilisé dans un très grand nombre de services en production. paho.golang est l'implémentation MQTT 5 plus récente, avec un paquet autopaho qui gère la reconnexion pour vous. Pour un nouveau projet MQTT 5, commencez par paho.golang ; pour une large compatibilité 3.1.1 et le plus grand corpus d'exemples, le client classique reste un choix solide.
package main
import (
"crypto/tls"
"fmt"
"math/rand"
"time"
mqtt "github.com/eclipse/paho.mqtt.golang"
)
func main() {
topic := "connectmq/demo/k3x8p1/libs/go"
opts := mqtt.NewClientOptions().
AddBroker("tls://broker.connectmq.com:8883").
SetClientID(fmt.Sprintf("libs-go-%06d", rand.Intn(1000000))).
SetTLSConfig(&tls.Config{MinVersion: tls.VersionTLS12}).
SetAutoReconnect(true)
client := mqtt.NewClient(opts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
panic(token.Error())
}
client.Subscribe(topic, 1, func(_ mqtt.Client, m mqtt.Message) {
fmt.Printf("%s %s\n", m.Topic(), m.Payload())
}).Wait()
client.Publish(topic, 1, false, "hello from Go").Wait()
time.Sleep(2 * time.Second)
client.Disconnect(250)
}
Consultez construire un client MQTT en Go pour l'arrêt propre et les payloads structurés.
Java et Kotlin : Paho et HiveMQ Client
Eclipse Paho Java propose deux paquets : org.eclipse.paho.client.mqttv3 pour MQTT 3.1.1 et org.eclipse.paho.mqttv5.client pour MQTT 5. Le HiveMQ MQTT Client est une alternative dotée d'API bloquantes, asynchrones et réactives, adaptée aux bases de code Reactor ou RxJava. Les deux fonctionnent aussi sous Android, ce qui explique pourquoi les applications Kotlin les utilisent souvent directement.
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import java.util.UUID;
public class LibsJava {
public static void main(String[] args) throws Exception {
String topic = "connectmq/demo/k3x8p1/libs/java";
String clientId = "libs-java-" + UUID.randomUUID().toString().substring(0, 8);
MqttClient client = new MqttClient("ssl://broker.connectmq.com:8883",
clientId, new MemoryPersistence());
MqttConnectOptions options = new MqttConnectOptions();
options.setAutomaticReconnect(true);
options.setCleanSession(true);
client.connect(options);
client.subscribe(topic, 1, (t, msg) ->
System.out.println(t + " " + new String(msg.getPayload())));
client.publish(topic, "hello from Paho Java".getBytes(), 1, false);
Thread.sleep(2000);
client.disconnect();
client.close();
}
}
Les utilisateurs de Spring Boot l'enveloppent généralement dans Spring Integration ; les patterns sont décrits dans notre guide du client MQTT Java et le tutoriel MQTT Android avec Kotlin.
C# et .NET : MQTTnet
MQTTnet est la bibliothèque .NET de référence et prend en charge MQTT 5, TLS et WebSocket. Entièrement asynchrone, elle s'intègre aux hosted services ASP.NET Core, aux applications .NET MAUI et à Unity. Attention, les versions majeures diffèrent : la version 5 a renommé la fabrique en MqttClientFactory, tandis que la version 4 utilise MqttFactory. L'extrait cible la version 5.
using MQTTnet;
using MQTTnet.Formatter;
var topic = "connectmq/demo/k3x8p1/libs/csharp";
var factory = new MqttClientFactory();
using var client = factory.CreateMqttClient();
client.ApplicationMessageReceivedAsync += e =>
{
Console.WriteLine($"{e.ApplicationMessage.Topic} {e.ApplicationMessage.ConvertPayloadToString()}");
return Task.CompletedTask;
};
var options = new MqttClientOptionsBuilder()
.WithTcpServer("broker.connectmq.com", 8883)
.WithClientId($"libs-cs-{Guid.NewGuid():N}"[..16])
.WithProtocolVersion(MqttProtocolVersion.V500)
.WithTlsOptions(o => o.UseTls())
.Build();
await client.ConnectAsync(options);
await client.SubscribeAsync(factory.CreateSubscribeOptionsBuilder()
.WithTopicFilter(topic).Build());
await client.PublishAsync(new MqttApplicationMessageBuilder()
.WithTopic(topic).WithPayload("hello from MQTTnet").Build());
await Task.Delay(2000);
await client.DisconnectAsync();
Le client bas niveau de MQTTnet ne se reconnecte pas tout seul : enveloppez donc la connexion dans une boucle ou un service en arrière-plan. Le tutoriel MQTTnet présente un pattern de hosted service résilient.
Rust : rumqttc
rumqttc est le client Rust le plus utilisé. Il sépare le handle du client d'une boucle d'événements que vous interrogez, ce qui vous donne un contrôle explicite sur la contre-pression. Il existe des modules MQTT 3.1.1 et MQTT 5.
use rumqttc::{AsyncClient, Event, MqttOptions, Packet, QoS};
use std::time::Duration;
#[tokio::main]
async fn main() {
let topic = "connectmq/demo/k3x8p1/libs/rust";
let mut opts = MqttOptions::new("libs-rust-k3x8p1", "broker.connectmq.com", 1883);
opts.set_keep_alive(Duration::from_secs(30));
let (client, mut eventloop) = AsyncClient::new(opts, 10);
client.subscribe(topic, QoS::AtLeastOnce).await.unwrap();
client.publish(topic, QoS::AtLeastOnce, false, "hello from rumqttc").await.unwrap();
loop {
match eventloop.poll().await {
Ok(Event::Incoming(Packet::Publish(p))) => {
println!("{} {}", p.topic, String::from_utf8_lossy(&p.payload));
}
Ok(_) => {}
Err(e) => {
eprintln!("connection error: {e}");
tokio::time::sleep(Duration::from_secs(2)).await;
}
}
}
}
Interroger à nouveau la boucle d'événements après une erreur, c'est ainsi que rumqttc se reconnecte. TLS nécessite l'un de ses feature flags TLS ; le guide rumqttc couvre cette configuration.
C et embarqué : Paho C, libmosquitto, PubSubClient, esp-mqtt
Pour les applications Linux natives, Eclipse Paho C propose des API synchrones et asynchrones avec prise en charge de MQTT 5, et libmosquitto est une alternative légère et éprouvée issue du projet Mosquitto.
#include <stdio.h>
#include <string.h>
#include "MQTTClient.h"
int main(void) {
MQTTClient client;
MQTTClient_connectOptions opts = MQTTClient_connectOptions_initializer;
MQTTClient_message msg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
const char *topic = "connectmq/demo/k3x8p1/libs/c";
char payload[] = "hello from Paho C";
MQTTClient_create(&client, "tcp://broker.connectmq.com:1883", "libs-c-k3x8p1",
MQTTCLIENT_PERSISTENCE_NONE, NULL);
opts.keepAliveInterval = 30;
opts.cleansession = 1;
if (MQTTClient_connect(client, &opts) != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "connect failed\n");
return 1;
}
msg.payload = payload;
msg.payloadlen = (int)strlen(payload);
msg.qos = 1;
msg.retained = 0;
MQTTClient_publishMessage(client, topic, &msg, &token);
MQTTClient_waitForCompletion(client, token, 10000L);
MQTTClient_disconnect(client, 10000);
MQTTClient_destroy(&client);
return 0;
}
Sur les microcontrôleurs, les compromis changent. PubSubClient est minuscule et simple, mais ne prend en charge que MQTT 3.1.1, publie en QoS 0 et dispose d'un tampon de paquets par défaut de 256 octets qu'il faut augmenter avec setBufferSize() pour les payloads JSON. AsyncMqttClient ajoute la publication en QoS 1 et 2 avec une conception non bloquante. Pour un firmware ESP32 de production, le composant esp-mqtt d'Espressif dans ESP-IDF prend en charge MQTT 5, TLS et WebSocket, et il est maintenu par le fabricant de la puce. Commencez par le tutoriel ESP32 MQTT pour du code Arduino fonctionnel, et par Paho MQTT C pour les appareils Linux.
Mobile : Swift, Kotlin, Flutter et React Native
Les clients mobiles font face à une contrainte que les serveurs ignorent : le système d'exploitation suspend les applications en arrière-plan et coupe les sockets inactifs. Quelle que soit la bibliothèque choisie, prévoyez des reconnexions fréquentes, utilisez des sessions persistantes ou des retained messages pour rattraper le retard, et recourez aux notifications push pour tout ce qui doit atteindre un téléphone en veille.
- iOS / macOS : CocoaMQTT prend en charge MQTT 5, TLS et WebSocket. Voir MQTT sur iOS avec Swift.
- Android : Paho Java ou le client HiveMQ depuis Kotlin, idéalement dans un composant sensible au cycle de vie.
- Flutter :
mqtt_clientcouvre les cibles serveur et navigateur à partir d'une seule base de code Dart. Voir le tutoriel MQTT Flutter. - React Native : MQTT.js sur WebSocket est la voie la plus courante, avec quelques polyfills. Voir React Native MQTT.
Les pièges qui ressemblent à des bugs de bibliothèque
La plupart des problèmes imputés à une bibliothèque sont en réalité des problèmes de configuration ou de conception. Vérifiez d'abord ceux-ci :
| Symptôme | Cause réelle | Correction |
|---|---|---|
| Boucle permanente connexion/déconnexion | Deux processus partagent un même client ID | Générez des ID uniques ; le broker abandonne l'ancienne session |
| Plus aucun message après reconnexion | Clean session sans réabonnement | Réabonnez-vous dans le callback de connexion, pas une seule fois au démarrage |
| La boucle d'événements se fige | Traitement bloquant dans un callback de message | Confiez le travail à une file, un pool de threads ou une tâche asynchrone |
| Gros payloads perdus silencieusement | Tampon client ou limite de taille du broker | Augmentez le tampon client ; respectez les limites du broker |
| Échec de la poignée de main TLS sur l'appareil | CA racine manquante ou horloge fausse | Installez le bundle CA et synchronisez l'heure via NTP avant la connexion |
| Doublons en QoS 1 | Comportement « au moins une fois » attendu | Rendez les handlers idempotents ; voir les niveaux de QoS MQTT expliqués |
La gestion de la reconnexion mérite une attention particulière en Python ; le guide de reconnexion paho-mqtt explique les réglages de backoff. Pour une approche systématique de la vérification d'un client avant livraison, lisez tester les clients MQTT, et gardez sous la main des exemples mosquitto_pub et mosquitto_sub comme second client indépendant lors du débogage.
Passer du serveur MQTT public gratuit à votre propre broker
Tous les extraits ci-dessus utilisent le serveur MQTT public gratuit, anonyme, parfait pour comparer les bibliothèques côte à côte : lancez l'abonné Python, publiez depuis Go, regardez le message arriver. Ce serveur public est toutefois partagé, lisible par tous et réservé aux tests ; les clients de production ont donc besoin d'identifiants et d'un broker isolé.
ConnectMQ est un broker MQTT managé qui fonctionne avec toutes les bibliothèques de ce guide, car il parle le MQTT 3.1.1 et 5.0 standard sur TCP 1883, TLS 8883, WebSocket 8083 et Secure WebSocket 8084 (chemin /mqtt). Lorsque vous créez un broker dans le portail, vous recevez un nom d'utilisateur, un mot de passe et un client ID. Adapter n'importe quel extrait ci-dessus se résume à trois lignes, illustrées ici pour paho-mqtt :
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID", protocol=mqtt.MQTTv5)
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set()
ConnectMQ associe les client ID aux identifiants émis : utilisez donc l'ID généré exactement tel quel. Si vous hésitez encore sur la manière d'héberger votre broker, notre guide du paysage des brokers MQTT cloud compare les options serverless, dédiées et bring-your-own-cloud.
Connectez n'importe quelle bibliothèque MQTT à ConnectMQ
Choisissez la bibliothèque adaptée à votre stack, exécutez son extrait sur broker.connectmq.com et, quand viendra le moment des topics privés, créez un broker gratuit sur app.connectmq.com. Le plan Serverless gratuit ne demande aucune carte bancaire et vous offre jusqu'à 25 connexions, une QoS jusqu'à 1 et des messages de 256 Ko, largement de quoi développer et tester des clients dans plusieurs langages à la fois.
Questions fréquentes
Quelle est la meilleure bibliothèque client MQTT ?
Il n'y en a pas une seule ; le bon choix est la bibliothèque maintenue qui correspond à votre langage et à votre modèle de concurrence. paho-mqtt pour Python, MQTT.js pour JavaScript, MQTTnet pour .NET et Paho ou rumqttc pour Go et Rust sont les choix par défaut courants et bien pris en charge.
Toutes les bibliothèques client MQTT prennent-elles en charge MQTT 5 ?
Non. Plusieurs bibliothèques populaires, dont PubSubClient pour Arduino et le client Paho Go classique, n'implémentent que MQTT 3.1.1. Si vous avez besoin d'abonnements partagés, de l'expiration des messages ou des reason codes, vérifiez la prise en charge de MQTT 5 avant d'adopter une bibliothèque.
Des clients écrits dans des langages différents peuvent-ils communiquer entre eux ?
Oui. Le broker achemine des octets, pas des objets d'un langage donné : un éditeur Python et un abonné C# interopèrent donc tant qu'ils s'accordent sur les topics et le format du payload. JSON est le format commun le plus simple pour commencer.
Quelle bibliothèque utiliser dans le navigateur ?
MQTT.js sur Secure WebSocket est le choix standard. Connectez-vous à wss://broker.connectmq.com:8084/mqtt, car les navigateurs ne peuvent pas ouvrir de sockets TCP bruts et les pages HTTPS bloquent les connexions WebSocket non sécurisées.
Pourquoi mon client fonctionne-t-il sur le serveur MQTT public gratuit mais pas sur un broker privé ?
Le plus souvent, il manque des identifiants, le client ID ne correspond pas à celui qui a été émis, ou TLS n'est pas activé. Vérifiez le reason code CONNACK renvoyé par votre bibliothèque : il vous indique précisément lequel de ces points pose problème.



