Une bonne configuration de bridge Mosquitto permet à un broker local sur Raspberry Pi de continuer à servir les appareils du réseau local tout en transférant exactement les topics de votre choix vers un broker cloud. Dans ce tutoriel, vous allez construire un bridge qui se connecte à ConnectMQ en TLS avec les identifiants du portail, remappe les topics pour que chaque site dispose de son propre namespace, redescend les commandes, met les messages en file pendant les coupures Internet et évite la boucle de messages classique. Chaque option est expliquée, pour que vous puissiez adapter le fichier au lieu de le copier aveuglément.
Comment fonctionne un bridge Mosquitto
Un bridge n'est pas un protocole particulier. Le broker Mosquitto local ouvre une connexion sortante vers le broker distant et se comporte comme un client MQTT ordinaire : il s'abonne d'un côté et republie de l'autre, selon les lignes topic de sa configuration. Cela a trois conséquences utiles :
- Aucun port entrant. Le Pi se connecte en sortie sur le port 8883, exactement comme un navigateur qui ouvre un site web. Votre routeur reste fermé.
- Le broker distant n'a besoin de rien de particulier. Tout broker conforme au standard accepte un bridge, car il voit simplement un client se connecter avec un nom d'utilisateur, un mot de passe et un client ID.
- Vous choisissez ce qui franchit la frontière. Seuls les topics correspondant à une ligne
topicsortent du site ou y entrent.
Dans cette installation, le côté distant est ConnectMQ, un broker MQTT managé. Le bridge s'authentifie avec les identifiants générés dans le portail, comme n'importe quel autre appareil. Si vous n'avez pas encore installé le broker local, suivez d'abord installer Mosquitto sur Raspberry Pi.
Sensors / PLC gateway / Node-RED (LAN)
| mqtt://pi:1883 (local users)
v
+---------------------------+
| Mosquitto on Raspberry Pi |
| bridge "connectmq" |
+---------------------------+
| mqtts://broker.connectmq.com:8883
| remote_username / remote_password / remote_clientid
v
+---------------------------+
| ConnectMQ cloud broker | dashboards, phones, other sites
+---------------------------+
Avant de commencer
- Un Raspberry Pi avec Mosquitto 2.0 en fonctionnement et au moins un listener local authentifié.
- Un broker cloud avec des identifiants. Inscrivez-vous sur le portail, choisissez une offre, créez un broker et copiez le nom d'utilisateur, le mot de passe et le client ID générés. Le client ID est lié à ces identifiants : le bridge doit l'utiliser tel quel.
- Un plan de nommage des topics. Décidez de l'apparence des topics locaux dans le cloud. Un préfixe de site comme
site1/évite que plusieurs Pi entrent en collision.
Pour une expérience rapide sans compte, vous pouvez relier le bridge au serveur MQTT public gratuit sur le port 1883, sans identifiants et avec n'importe quel client ID unique, en utilisant un préfixe aléatoire comme connectmq/demo/3c7d52/. Tout y est lisible publiquement : réservez-le aux tests et n'utilisez que des données fictives.
La configuration complète du bridge Mosquitto
Créez /etc/mosquitto/conf.d/bridge-connectmq.conf :
# ---- Connexion ----
connection connectmq
address broker.connectmq.com:8883
bridge_protocol_version mqttv311
try_private false
start_type automatic
restart_timeout 5 60
keepalive_interval 60
# ---- TLS ----
bridge_capath /etc/ssl/certs
bridge_insecure false
# ---- Identifiants issus du portail ConnectMQ ----
remote_clientid YOUR_CLIENT_ID
remote_username YOUR_USERNAME
remote_password YOUR_PASSWORD
# ---- Session et mise en file ----
cleansession false
local_clientid bridge-connectmq-local
# ---- Topic d'état (publié côté distant) ----
notifications true
notifications_local_only false
notification_topic site1/bridge/state
# ---- Mappage des topics ----
# Télémétrie montante : local "sensors/#" -> distant "site1/sensors/#"
topic sensors/# out 1 "" site1/
# États machines montants, valeurs retained préservées
topic machines/+/state out 1 "" site1/
# Commandes descendantes : distant "site1/cmd/#" -> local "cmd/#"
topic cmd/# in 1 "" site1/
Redémarrez et suivez le journal :
sudo chmod 0640 /etc/mosquitto/conf.d/bridge-connectmq.conf
sudo chown root:mosquitto /etc/mosquitto/conf.d/bridge-connectmq.conf
sudo systemctl restart mosquitto
sudo journalctl -u mosquitto -f
Vous devriez voir Connecting bridge connectmq (broker.connectmq.com:8883) sans erreur à la suite. Le changement de permissions est important, car le fichier contient le mot de passe distant.
Option par option
| Option | Valeur ici | Pourquoi |
|---|---|---|
address |
broker.connectmq.com:8883 |
Port TLS du broker cloud |
bridge_protocol_version |
mqttv311 |
Largement supporté ; le bridge en MQTT 5 est aussi possible sur les versions récentes de Mosquitto |
try_private |
false |
Évite un drapeau de bridge propre à Mosquitto que d'autres brokers peuvent refuser |
restart_timeout |
5 60 |
Temporisation croissante de 5 s jusqu'à 60 s entre les tentatives de reconnexion |
bridge_capath |
/etc/ssl/certs |
Le magasin de CA du système valide le certificat Let's Encrypt du broker |
bridge_insecure |
false |
Gardez toujours la vérification du nom d'hôte activée |
remote_clientid |
Client ID du portail | Doit correspondre aux identifiants délivrés |
cleansession |
false |
Conserve les sessions pour que les messages QoS 1 soient mis en file pendant les coupures |
notifications |
true |
Publie 1 à la connexion du bridge et 0 (en last will) à sa chute |
notification_topic |
site1/bridge/state |
Garde l'état dans votre propre namespace |
Comprendre la ligne topic
La syntaxe est topic <pattern> <direction> <qos> <local-prefix> <remote-prefix>. Mosquitto retire le préfixe local d'un topic local et ajoute le préfixe distant lors du transfert sortant, et fait l'inverse pour in. Avec un préfixe local vide (écrit "") et le préfixe distant site1/ :
- Le topic local
sensors/boiler/tempdevient le topic distantsite1/sensors/boiler/temp. - Le topic distant
site1/cmd/pump1/setdevient le topic localcmd/pump1/set.
Notez que le préfixe distant se termine par une barre oblique. Sans elle, vous obtenez site1sensors/..., une erreur facile à commettre et difficile à repérer.
La QoS sur le bridge
La QoS d'une ligne topic est la valeur maximale utilisée à travers le bridge. QoS 1 est le choix pragmatique : elle garantit la livraison grâce aux acquittements et est supportée sur toutes les offres, y compris l'offre Serverless gratuite, qui plafonne la QoS à 1. N'utilisez QoS 2 que si votre offre la supporte et que les données ne tolèrent vraiment aucun doublon. L'article les niveaux de QoS MQTT expliqués détaille les compromis.
Mise en file pendant les coupures Internet
Avec cleansession false, le broker local conserve la session du bridge pendant que la connexion est coupée et met en file les messages QoS 1 qui lui sont destinés. Au retour du lien, l'arriéré se vide vers le cloud. La file est bornée par max_queued_messages (et éventuellement max_queued_bytes) dans votre configuration principale. Dimensionnez-la pour la plus longue coupure que vous voulez couvrir ; sur un Pi avec carte SD, restez modéré, car les files persistées sont écrites sur disque à chaque autosave. Les messages QoS 0 ne sont pas mis en file, raison de plus pour faire passer la télémétrie par le bridge en QoS 1.
N'oubliez pas que le côté cloud applique aussi ses propres limites. Si un long arriéré arrive d'un seul coup, un broker avec des quotas par offre et une protection contre le flood peut le limiter ; les coupures très longues sont donc mieux gérées par un tampon applicatif comme celui du guide de mise en tampon des messages hors ligne.
Tester le bridge de bout en bout
Abonnez-vous côté cloud. Avec le serveur public, vous pouvez utiliser mosquitto_sub directement ; avec un broker privé, utilisez un second jeu d'identifiants ou le client MQTT intégré au navigateur dans le portail :
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-u YOUR_USERNAME_2 -P YOUR_PASSWORD_2 -i YOUR_CLIENT_ID_2 \
-t 'site1/#' -v
Publiez localement sur le Pi :
mosquitto_pub -h localhost -u sensors -P 'sensors-password' -i t1 -q 1 \
-t sensors/boiler/temp -m 64.2
L'abonné cloud affiche site1/sensors/boiler/temp 64.2 et site1/bridge/state 1. Testez maintenant la voie descendante. Abonnez-vous localement à cmd/#, puis publiez côté cloud sur site1/cmd/pump1/set. Le message arrive localement sous cmd/pump1/set.
Enfin, testez une coupure : arrêtez le réseau sur le Pi (sudo nmcli networking off), publiez quelques messages QoS 1 localement, réactivez le réseau et regardez-les arriver dans le cloud. Le topic d'état du bridge passe à 0 pendant la coupure, valeur délivrée par le broker en tant que last will du bridge.
Éviter les boucles dans la configuration de votre bridge Mosquitto
Une boucle se produit quand un message transféré en sortie revient en entrée et repart en sortie. La cause la plus fréquente est une règle both, ou des motifs in et out qui se chevauchent sur les mêmes topics :
# Dangereux : tout ce qui est sous site1/ fait des allers-retours
topic # both 1 "" site1/
Séparez les sens sur des sous-arborescences distinctes : télémétrie et états en out, commandes en in sous une autre branche (cmd/). Si vous avez vraiment besoin de both, préférez le bridge MQTT 5 avec des abonnements no-local lorsque votre version de Mosquitto le permet, et testez soigneusement. Ne faites jamais passer # sans préfixe, dans aucun sens.
Plusieurs sites, un seul broker cloud
Chaque Pi reçoit ses propres identifiants et son propre préfixe (site1/, site2/, ...). Les tableaux de bord s'abonnent à +/sensors/# pour voir tous les sites, ou à un seul préfixe pour un site donné. Comme chaque bridge a un client ID unique lié à ses identifiants, révoquer un site n'affecte jamais les autres. Les offres Serverless payantes ajoutent les shared subscriptions, utiles quand plusieurs consommateurs cloud doivent se répartir le flux combiné. Les sites industriels peuvent aller plus loin et adopter une hiérarchie de type ISA-95 comme enterprise/site/area/line/cell, que le portail détecte et affiche dans sa vue des appareils.
Dépannage
| Message de journal ou symptôme | Cause | Solution |
|---|---|---|
Connection Refused: not authorised |
Identifiants ou client ID erronés | Recopiez les trois depuis le portail |
certificate verify failed |
Magasin de CA manquant ou heure incorrecte | Installez ca-certificates, vérifiez NTP avec timedatectl |
| Le bridge se connecte, rien n'arrive | Motif de topic ou préfixe incohérent | Pensez à la barre oblique finale des préfixes |
| La connexion tombe toutes les quelques secondes | Un autre client utilise le même client ID | Un client ID par connexion |
| Messages perdus pendant les coupures | QoS 0 ou cleansession true |
Utilisez QoS 1 et cleansession false |
| Tempête de messages après activation du bridge | Boucle due à des règles in/out qui se chevauchent | Sous-arborescences séparées pour chaque sens |
Reliez votre Pi à ConnectMQ
Créez un broker Serverless gratuit sur app.connectmq.com, sans carte bancaire, collez le nom d'utilisateur, le mot de passe et le client ID générés dans votre fichier de bridge et regardez les topics de votre site apparaître dans l'explorateur de topics en direct du portail. Pour la conception plus globale de la passerelle autour de ce bridge, lisez le Raspberry Pi comme passerelle IoT, et pour toute la série Pi, le tutoriel MQTT sur Raspberry Pi.
Questions fréquentes
ConnectMQ a-t-il besoin d'une fonctionnalité de bridge spéciale pour Mosquitto ?
Non. Le bridge Mosquitto se connecte comme un client MQTT ordinaire avec le nom d'utilisateur, le mot de passe et le client ID du portail ; toutes les offres conviennent donc.
Faut-il faire le bridge en MQTT 3.1.1 ou en MQTT 5 ?
MQTT 3.1.1 est le choix le plus simple et le plus éprouvé pour les bridges. Les versions récentes de Mosquitto supportent le bridge mqttv50 si vous avez besoin des fonctionnalités MQTT 5 sur le lien du bridge.
Pourquoi mettre try_private à false ?
Lorsqu'il est activé, Mosquitto signale qu'il s'agit d'un bridge à l'aide d'un drapeau de protocole non standard prévu pour les liaisons Mosquitto vers Mosquitto. Le désactiver garde la connexion entièrement standard pour les autres brokers.
Combien de messages le bridge met-il en file pendant une coupure ?
Autant que le permettent max_queued_messages et max_queued_bytes, pour les messages QoS 1 et 2 avec cleansession false. Les messages QoS 0 sont abandonnés tant que le lien est coupé.



