6.5 KiB
Les sujets
En MQTT, un sujet (ou topic en anglais) est une chaîne de caractères qui identifie une catégorie ou un canal de communication. Les clients MQTT peuvent s'abonner à un ou plusieurs sujets pour recevoir les messages publiés sur ces sujets.
Lorsqu'un client publie un message sur un sujet particulier, tous les clients qui se sont abonnés à ce sujet recevront ce message. Les sujets sont organisés sous forme de hiérarchie à l'aide de barres obliques (/) pour séparer les différents niveaux.
Prenons un exemple concret. Un capteur de température dans la chambre 1 publie sa mesure sur le sujet maison/chambre1/temperature avec pour charge utile 19.8. Au même moment, un autre capteur publie l'humidité de la cuisine sur maison/cuisine/humidite avec la valeur 62. Home Assistant, abonné à maison/chambre1/temperature, recevra uniquement la première information ; un dashboard Grafana abonné aux deux sujets recevra les deux.
Quelques bonnes pratiques pour nommer les sujets :
- Toujours en minuscules, sans accents ni espaces —
maison/chambre1/temperatureplutôt queMaison/Chambre 1/Température. - Du plus général au plus spécifique, de gauche à droite —
maison/etage1/chambre1/capteur3se lit naturellement. - Pas de
/en début de sujet :/maison/chambre1crée un premier niveau vide, source d'erreurs subtiles. - Préférer des noms parlants à des identifiants opaques —
chambre1plutôt quedev_8a3f.
Les sujets sont un élément clé de la flexibilité et de l'extensibilité de MQTT, permettant une communication efficace et ciblée entre les différents clients de l'écosystème.
Sujets réservés
MQTT définit plusieurs sujets réservés (ou reserved topics) qui ont une signification particulière et qui ne doivent pas être utilisés pour la publication de messages personnalisés. Tous les sujets réservés commencent par le caractère $, ce qui permet de les distinguer immédiatement des sujets applicatifs. Voici quelques exemples :
$SYS/#: utilisé par le broker pour publier des informations système le concernant — statistiques de performance, informations de connexion des clients, etc.$SYS/broker/version: version du broker MQTT.$SYS/broker/uptime: temps d'activité du broker depuis son dernier démarrage.$SYS/broker/clients/connected: nombre de clients actuellement connectés.$SYS/broker/messages/received: nombre total de messages reçus depuis le démarrage.
Concrètement, on peut s'abonner à $SYS/# depuis un client MQTT pour superviser la santé du broker en temps réel. Avec mosquitto_sub :
mosquitto_sub -h localhost -t '$SYS/#' -v
renverra en continu des lignes comme :
$SYS/broker/uptime 12453 seconds
$SYS/broker/clients/connected 7
$SYS/broker/load/messages/received/1min 142
Il ne faut pas utiliser ces sujets réservés pour publier des messages personnalisés, car cela peut perturber le fonctionnement normal du broker ou des clients MQTT qui s'attendent à y recevoir des informations système spécifiques.
Caractère générique
En MQTT, le symbole # est un caractère générique utilisé comme joker pour s'abonner à tous les sous-sujets d'un certain niveau et de tous les niveaux inférieurs. Il ne peut apparaître qu'en dernière position d'un filtre d'abonnement.
Par exemple, si un client s'abonne au sujet maison/chambre1/#, il recevra les messages publiés sur :
maison/chambre1/temperaturemaison/chambre1/humiditemaison/chambre1/lumiere/plafondmaison/chambre1/lumiere/chevet/etat
…et tous les autres sous-sujets, quelle que soit leur profondeur. À noter : maison/chambre1/# inclut aussi le sujet maison/chambre1 lui-même s'il existe.
Un cas d'usage typique : un logger qui veut archiver toute l'activité de la maison s'abonne simplement à maison/# et capte l'intégralité des messages échangés sur cette branche.
L'utilisation du joker # peut avoir des conséquences importantes sur le trafic réseau et la charge de travail du broker, en particulier pour les hiérarchies importantes avec de nombreux sous-sujets. S'abonner à # tout court (autorisé par la plupart des brokers, à confirmer dans la doc) reviendrait à recevoir absolument tous les messages — utile pour du débogage ponctuel, à proscrire en production.
Quelques règles à respecter pour que le filtre soit valide :
#doit être seul dans son niveau :maison/chambre1#est invalide, il faut écriremaison/chambre1/#.#doit être le dernier caractère :maison/#/temperatureest invalide.- On ne peut pas publier sur un sujet contenant
#— les jokers sont réservés aux abonnements.
Caractère générique +
MQTT définit un autre caractère générique, le symbole +, qui correspond à exactement un seul niveau de la hiérarchie. Contrairement à #, il peut être placé à n'importe quel niveau du filtre, et même apparaître plusieurs fois.
Par exemple, si un client s'abonne au sujet maison/+/temperature, il recevra les messages publiés sur :
maison/chambre1/temperature✓maison/cuisine/temperature✓maison/salon/temperature✓maison/chambre1/capteur1/temperature✗ (deux niveaux entremaisonettemperature)maison/temperature✗ (aucun niveau entre les deux)
C'est exactement ce qu'on attend pour récupérer toutes les températures de la maison, sans capter au passage l'humidité ou la luminosité.
On peut combiner plusieurs + dans un même filtre. Par exemple, maison/+/+/etat capte l'état de tous les équipements de toutes les pièces : maison/salon/lampe1/etat, maison/cuisine/four/etat, etc.
Et on peut associer + et # dans un même abonnement. Par exemple, maison/+/capteurs/# capte tout ce qui concerne les capteurs de n'importe quelle pièce, à n'importe quelle profondeur :
maison/salon/capteurs/temperature✓maison/cuisine/capteurs/humidite/valeur✓maison/chambre1/lampe/etat✗
Comme pour #, le symbole + ne peut être utilisé que dans un abonnement, jamais dans une publication.
Récapitulatif
| Filtre | Correspond à |
|---|---|
maison/chambre1/temperature |
exactement ce sujet |
maison/+/temperature |
les températures de chaque pièce (un seul niveau) |
maison/chambre1/# |
tout ce qui est publié sous chambre1 (profondeur quelconque) |
maison/+/+/etat |
l'état des équipements de chaque pièce |
# |
tous les sujets applicatifs (à utiliser avec parcimonie) |
$SYS/# |
toutes les infos système du broker |