5. Laurent Guérin - @ltguerin
MQTT
5
MQTT 3.1 MQTT 3.1.1
Protocole de transport « léger » conçu pour des
échanges de type « M2M » (Machine to Machine)
et donc « IoT »
https://mqtt.org/
https://www.oasis-open.org/committees/mqtt
IBM
Andy Stanford-Clark
EUROTECH
Arlen Nipper
MQTT = MQ (Message Queuing) Telemetry Transport
6. Laurent Guérin - @ltguerin
MQTT – TCP/IP
6
TCP/IP stack
MQTT
Ethernet Hardware
Application
Encryption
MQTT
Ethernet Hardware
Application
TCP/IP stack
SSL / TLS
MQTT est basé sur la stack TCP/IP
( pour la sécurité : MQTT over TLS )
tcp://host:1883 ssl://host:8883
7. Laurent Guérin - @ltguerin
MQTT – Cas d’utilisation
7
“MQTT is
designed to
use bandwidth
and batteries
sparingly”
IoT
Event Bus Messaging
Chat
M2M
8. Laurent Guérin - @ltguerin
MQTT – Messages
8
Message payload :
un simple tableau d’octets
(texte, binaire, etc )
Le header MQTT
se résume
généralement
à 2 octets
Message max size : 256 MB
9. Laurent Guérin - @ltguerin
MQTT – Pattern « Publish/Subscribe »
9
BROKER
MQTT
PUB
SUB
SUB
SUB
Publishing clients
Receiving clients
10. Laurent Guérin - @ltguerin
MQTT – Publish/Subscribe = Découplage
10
PUBLISHER
BROKER
SUBSCRIBER
PUB
SUB
L’un ne sait pas que l’autre existe
(et réciproquement)
Temps
Découplage dans l’espace + Découplage dans le temps
12. Laurent Guérin - @ltguerin
Mosquitto le broker de référence
Mosquitto : broker MQTT
de la fondation Eclipse
écrit en C (258 kb)
https://mosquitto.org/
12
https://iot.eclipse.org/
13. Laurent Guérin - @ltguerin
Autres brokers MQTT
Quelques brokers MQTT :
Moquette : broker écrit en Java (fondation Eclipse)
HiveMQ : "enterprise MQTT broker" https://www.hivemq.com/
VerneMQ : "high-performance, distributed MQTT broker" https://vernemq.com/
EMQ : broker écrit en Erlang http://emqtt.io/
CloudMQTT : comme son nom l’indique… https://www.cloudmqtt.com/
Brokers « MQ classiques » supportant le protocole MQTT :
ActiveMQ : http://activemq.apache.org/mqtt.html
RabbitMQ : MQTT Adapter https://www.rabbitmq.com/mqtt.html
(MQTT as of 3.0 / currently targeting version 3.1.1 of the spec).
13
cf MQTT implementations : https://en.wikipedia.org/wiki/Comparison_of_MQTT_Implementations
14. Laurent Guérin - @ltguerin
Les brokers MQTT sont partout
14
Raspberry Pi
Smartphone
Cloud
Laptop
Server
16. Laurent Guérin - @ltguerin
MQTT – Clients prêts à l’emploi
16
Extension pour Chrome
MQTT.fx
Ligne de commande :
Apps
pour
Android
& iOS
etc...
BROKER
17. Laurent Guérin - @ltguerin
MQTT – Développer un client
17
https://www.eclipse.org/paho/
"Eclipse Paho project provides open-source
client implementations of MQTT"
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.0</version>
</dependency>
Java / pom.xml :
Librairie pour Java SE 1.7 et +
18. Laurent Guérin - @ltguerin
MQTT – Développer un client
18
Avec Paho/Java le client MQTT est représenté par
la classe « MqttClient »
Principales méthodes :
• connect
• disconnect
• reconnect
• close
• publish
• subscribe
• unsubscribe
Les erreurs sont gérées via l’exception « MqttException »
19. Laurent Guérin - @ltguerin
MQTT – Connexion d’un client
19
Un client se connecte à un broker MQTT au niveau « TCP »
Informations nécessaires pour se connecter
le hostname
le port ( par défaut 1883 )
un client-id (identifiant unique)
Il peut également spécifier des options lors de la connexion
CLIENT BROKER
tcp://localhost:1883
1 - Connexion
2 - Dialogue
3 - Déconnexion
Client-Id
21. Laurent Guérin - @ltguerin
MQTT – Exemple en Java
21
NB : « connect » crée un pool de threads. Les threads restent actifs jusqu’au « close »
(les threads sont encore actifs même après « disconnect » )
22. Laurent Guérin - @ltguerin
MQTT – Clients
22
Classiquement 2 types de clients : Publisher & Subscriber
Techniquement un client MQTT n’est pas spécialisé,
un même client peut faire à la fois du Publish et du Subcribe
CLIENT 1 BROKER CLIENT 2
Publie un « message » Souscrit pour recevoir
des messages
CLIENT 1 BROKER CLIENT 2
PUB SUB
PUB
PUB SUB
24. Laurent Guérin - @ltguerin
MQTT – Clients & topics
24
Tous les messages envoyés sont associés à un « topic »
Techniquement un « topic » identifie un canal (une file de messages)
L’utilisation des « topics » permet de définir une sémantique
CLIENT
« PUB »
BROKER CLIENT
« SUB »
Publie un message
associé à un topic
Souscrit pour recevoir
les messages d’un topic
ou de plusieurs topics
pub(topic,data) sub(topic)
Publie le message
à tous les clients
abonnés au topic
pub
topic
25. Laurent Guérin - @ltguerin
MQTT – Topics
25
Un « topic » peut être vu comme un canal de communication
entre 1 « publisher » et N « subscribers »
La création des « topics » est implicite,
dès qu’un « publisher » émet un message sur un nouveau « topic » il est
automatiquement créé dans le « broker »
26. Laurent Guérin - @ltguerin
MQTT – Structure des topics
26
Un topic est identifié par une chaine de caractères UTF-8
(au moins 1 caractère, espaces autorisés)
Longueur max : 65535 bytes (64 kb – 1)
( UTF-8 : 1 character can require up to 4 bytes to encode )
Les topics sont organisés selon une structure arborescente
Un nom de topic est composé de
1 à N niveaux séparés par un « / »
Exemples :
Les noms de topics commençant par « $ » sont réservés pour les statistiques internes du broker.
Exemples : $SYS/broker/clients/connected $SYS/broker/uptime
home/groundfloor/livingroom/temperature
devfest/france/brest
building
floor-1 floor-2
room-1 room-2
templight
27. Laurent Guérin - @ltguerin
MQTT – Topics wildcards
27
Les subcribers sont généralement intéressés par plusieurs topics
Plutôt que de s’abonner spécifiquement à chaque topic il est possible d’utiliser
des « wildcards » :
« + » : single level wildcard
« # » : multi level wildcard
Exemples :
home/groundfloor/livingroom/temperature
home/groundfloor/+/temperature
home/groundfloor/#
home/groundfloor/+/+
home/groundfloor/livingroom/temperature
home/groundfloor/kitchen/temperature
home/groundfloor/livingroom/temperature
home/groundfloor/livingroom/brightness
home/groundfloor/kitchen/temperature
home/groundfloor/kitchen/ brightness
31. Laurent Guérin - @ltguerin
MQTT – Quality of Service : « QoS »
MQTT propose 3 niveaux de qualité de service pour les échanges
entre un client et un broker MQTT :
QoS level 2
QoS level 1
QoS level 0
31
C’est le client qui choisit
le niveau de QoS
QoS = 0/1/2
CLIENT
BROKER
CLIENTCLIENT
CLIENT
QoS
QoS
QoS
QoS
+
-
32. Laurent Guérin - @ltguerin
MQTT – QoS level 0 (au plus une fois)
QoS 0 : "at-most-once"
En mode « best effort », les messages sont remis en fonction des
capacités du réseau (TCP/IP).
L’acheminement des messages n’est pas garanti.
32
“fire and
forget”
0 .. 1
MQTT
CLIENT
MQTT
BROKER
PUBLISH QoS 0
(pas de retour)
33. Laurent Guérin - @ltguerin
MQTT – QoS level 1 (au moins une fois)
QoS 1 : "at-least-once"
L’acheminement des messages est garanti au moins une fois
(il peut y avoir des doublons)
L’émetteur conserve le message et le republie (avec le flag
« DUP ») jusqu’à ce qu’il reçoive l’accusé de réception
(« PUBACK » packet)
33
MQTT
CLIENT
MQTT
BROKER
PUBLISH QoS 1
PUBACK
“fire and
confirm”
1 (.. N)
PUBLISH "DUP"
34. Laurent Guérin - @ltguerin
MQTT – QoS level 2 (exactement une fois)
QoS 2 : "exactly-once"
L’acheminement des messages est garanti et sans doublon
34
MQTT
CLIENT
MQTT
BROKER
PUBLISH QoS 2
PUBREC
1
PUBREL
PUBCOMP
Niveau de qualité
le plus élevé
=> plus d’échanges
réseau
35. Laurent Guérin - @ltguerin
MQTT – « end to end » QoS
La qualité de service globale pour 2 clients communicants via un broker
MQTT est déterminée par la combinaison des 2 QOS
C’est le niveau le plus bas
qui détermine le niveau de
qualité globale
35
PUBLISHER BROKER SUBSCRIBER
Overall QoS = Min(X,Y)
QoS X QoS Y
QOS PUBLISH QOS SUBSCRIBE OVERALL QOS
0 2 0
1 2 1
2 1 1
2 2 2
36. Laurent Guérin - @ltguerin
MQTT – Exemple en Java
36
Par défaut :
QoS = 1
Exemple de « Publish » avec QoS = 2
Exemple de « Subscribe » avec QoS = 2
ou (sans objet MqttMessage) :
38. Laurent Guérin - @ltguerin
MQTT – Par défaut : « non persistent session »
38
CLIENT
« PUB »
BROKER
mosquitto_pub
-h localhost
-t a/b/c
-m blabla
OK Message reçu
CLIENT
« SUB »
mosquitto_sub
-h localhost
-t a/b/c
Avec un subscriber à l’écoute …
1
2
39. Laurent Guérin - @ltguerin
MQTT – Par défaut : « non persistent session »
39
CLIENT
« PUB »
BROKER
mosquitto_pub
-h localhost
-t a/b/c
-m blabla
Pas de subscriber connecté
au moment du “pub”
“MQTT is not a message queue by definition”
Sans aucun subscriber à l’écoute …
BROKER
CLIENT
« SUB »
mosquitto_sub
-h localhost
-t a/b/c
1
2
Rien Message perdu !
40. Laurent Guérin - @ltguerin
MQTT – Session
40
CLIENT
BROKER
La session contient des états qui sont stockés côté client et côté serveur.
Par défaut la session est nettoyée entre chaque connexion.
Quand un client se connecte à un broker pour la première fois
une session MQTT est créée implicitement
SESSION
SESSION
SESSIONCLIENT
SESSION
Une session
identifie
l’attachement
d’un client à un
serveur.
CONNECT (ClientID1)
CONNECT (ClientID2)
ClientID1
ClientID2
41. Laurent Guérin - @ltguerin
MQTT – Session / Contenu
41
CLIENT BROKER
SESSION SESSION
• Messages QoS 1 et QoS 2
envoyés au serveur et qui n’ont pas encore
reçu l’acquitement
• Messages QoS 2 reçus du serveur, mais
qui n’ont pas été complètement acquittés
• Messages QoS 1 et QoS 2
envoyés au client et qui n’ont pas encore
reçu l’acquitement
• Les messages QoS 2 reçus du client, mais
qui n'ont pas été complètement acquittés
• Les souscriptions du client (topics)
• Messages QoS 1 et QoS 2 en attente de
transmission au client (et optionnellement
les messages QoS 0 )
Les informations des sessions peuvent
être stockées sur le filesystem.
Notion de « persistent datastores »
Ex : fichier mosquitto.dbEx : fichier {client-id}/.lck
42. Laurent Guérin - @ltguerin
MQTT – Session & « clean session »
42
Par défaut la session est nettoyée à chaque connexion
Le flag « clean session » permet de déterminer le type de connexion :
• True : « non persistent session » (par défaut)
• False : « persistent session »
mosquitto_sub -h localhost -t a/b/# -q 2 -i ID1 -c -c :
disable clean session
“Do not clean”
45. Laurent Guérin - @ltguerin
Exemple : Sensors Outils de monitoring
45
MQTT consumer
[[inputs.mqtt_consumer]]
servers = ["mosquitto:1883"]
qos = 0
topics = [ "device/a" ]
data_format = "value"
data_type = "float"
mqtt_blackbox_exporter
PUB
SUB
SUB
46. Laurent Guérin - @ltguerin
Démo
46
sensor
temperature
sensor
humidity
devfest/bdm/temperature
devfest/bdm/humidity
logger
SUB
devfest/bdm/#
tcp://iot.eclipse.org:1883PUB
PUB
47. Laurent Guérin - @ltguerin
Démo
47
door
sensor
temperature
sensor
humidity
devfest/bdm/temperature
devfest/bdm/humidity
devfest/bdm/door/command
devfest/bdm/door/state
door
control
Commande
« O » open
« C » close
logger
SUB
devfest/bdm/#
tcp://iot.eclipse.org:1883
Changement d’état :
« O » open
« C » closed
PUB
PUB
PUB
PUB
SUB
48. Laurent Guérin - @ltguerin
Démo
48
door
sensor
temperature
sensor
humidity
devfest/bdm/temperature
devfest/bdm/humidity
devfest/bdm/door/command
devfest/bdm/door/state
door
control
Commande
« O » open
« C » close
logger
SUB
devfest/bdm/#
tcp://iot.eclipse.org:1883
Changement d’état :
« O » open
« C » closed
Browser
Dashboard
http tcp
PUB
PUB
PUB
PUB
SUB
PUB
SUB
49. Laurent Guérin - @ltguerin
WebSocket
Frame
MQTT over WebSockets
49
SERVER
MQTT
Server
HTTP
Server / websocket
BROWSER
MQTT JavaScript
client
TCP
WebSocket
lighttpd +
mod_websocket
Mosquitto
MQTT
message
WebSocket :
• Protocole normalisé par l’IETF en 2011
• Interface de programmation normalisée par le W3C
• Supporté par tous les navigateurs
• Canal de communication full-duplex sur socket TCP
• Permet de faire du « push » du serveur vers le client