Rest & Pub-Sub : protocole hybride pour l'IoT
L’avènement de l’Internet des Objets (IoT) depuis une dizaine d’années a fait apparaitre des problématiques propres aux protocoles de communications liées à ces objets. En effet, l’échange de données dans ce contexte nécessite de tenir compte (au moins) des paramètres suivants :
- Autonomie énergétique souvent limitée
- Faible puissance des processeurs et taille réduite de la mémoire
- Disponibilité « aléatoire » de l’accès aux réseaux de communication
De nombreux protocoles cohabitent et la littérature du domaine foisonne d’exemples autour des réseaux dédiés (LORA, Sigfox, etc.) et des protocoles applicatifs (OPC-UA, MQTT, CoaP, XMPP) mais force est de constater que dans la réalité, ces solutions ne répondent pas toujours aux besoins des concepteurs qui leurs préfèrent encore le protocole HTTP. Celui-ci offre l’avantage d’implémenter un protocole applicatif (REST) en même temps qu’un protocole de transport de haut niveau (TCP/IP) permettant de passer les pare-feu. Cependant, la version actuelle d’HTTP ne répond pas vraiment aux critères énoncés précédemment. Depuis quelques années émerge donc l’idée d’enrichir HTTP pour créer un protocole hybride qui mêlerait les avantages de REST avec ceux proposés par les mécanismes de type Publish/Subscribe (MQTT, AMQP, JMS, etc.). En attendant cette éventuelle évolution, peut-on envisager de mettre en place un mécanisme de type Pub/Sub avec le protocole Websocket au-dessus d’HTTP ?
MQTT
MQTT, Message Queuing Telemetry Transport, est un protocole publish/subscribe se basant sur le protocole TCP/IP. Il a été créé par Andy Stanford-Clark et Arlen Nipper.
De façon concrète, MQTT permet à des appareils de publier des informations sur un sujet donné sur un broker (un serveur qui fonctionne comme un coursier) qui va les retransmettre aux appareils abonnés à ce sujet.
MQTT gère aussi la qualité de service (d'une qualité 0 à une qualité 2):
Qualité 0 : le client qui publie une donnée ne reçoit aucune information par rapport à la confirmation de son arrivée.
Qualité 1 : le client qui publie reçoit la confirmation ou non que la donnée publiée a été reçue par le broker.
Qualité 2 : le client qui publie reçoit la confirmation ou non que la donnée donnée publiée a été reçue par le broker ainsi qu'un message lui indiquant que le client qui s'abonne a reçu la donnée.
Mosquitto
Mosquitto est un broker open-source qui se sert du protocole MQTT. Il permet une fois installé de se familiariser avec MQTT et le "publish/subscribe".
Nous nous en sommes servi ici sur une MachineVirtuel en publiant en localhost:
Sur un premier terminal on s'abonne à un topic "température" et sur un deuxième terminal, on publie ensuite sur ce même topic des nombres (qui s'apparentent à des températures). Au fur et à mesure que nous publions ces informations, nous les recevons sur le premier terminal. Mosquitto remplit bien ici son rôle de broker.
Pub/Sub avec Python
Nous avons ensuite développer un client publisher et un client subscriber en python grâce à la librairie paho-mqtt. Pour plus de simplicité et éviter des problèmes de timing, nous avons tout regrouper en un seul programme :
import paho.mqtt.client as mqtt import time broker="test.mosquitto.org" def envoi_message(client, QoS, message): print("message reçu :", str(message.payload.decode("utf-8"))) client= mqtt.Client("client_test") client.on_message=envoi_message client.connect(broker) print("connection") client.loop_start() client.subscribe("Cafetière/temperature_cafe") print("Abonnement...") time.sleep(1) pub= input("entrez une température (un nombre):") print("Publication...") time.sleep(1) client.publish("Cafetière/temperature_cafe",pub +"°C") time.sleep(1) client.disconnect() print("deconnection") client.loop_stop()
Comme broker, nous nous sommes servi ici d'un broker mis en libre service par mosquitto.
REST
REST (Representational State Transfer) aussi appeler restful est une architecture logicielle inventée par Roy Fielding qui se sert des verbes HTTP comme identifiant des opérations et des réponses HTTP comme représentation des ressources.
Une architecture REST est définie par 5 règles/contraintes :
- Client–serveur
- Sans état
- Avec mise en cache
- En couches
- Interface uniforme :
L'interface uniforme est la contrainte fondamentale d'une architecture REST car c'est celle-ci qui permet à chaque composant d'évoluer indépendamment. Elle est définie par 4 contraintes :
- Identification des ressources dans les requêtes
- Manipulation des ressources par des représentations
- Messages auto-descriptifs
- Hypermédia comme moteur d'état de l'application
Service pub/sub avec REST
On peut réaliser un équivalent de service pub/sub avec REST à l'aide de GET et de POST qui agissent sur une base de données gérée par un serveur :
Cette méthode comprend cependant de nombreux problèmes, notamment le fait que le client 1 ne sait pas si le client 2 a posté une donnée sur le serveur. On ne peut pas vraiment parler ici de service publish/subscribe car il n'y a pas d'abonnement, le client qui devrait s'abonner doit aller récupérer lui-même la donnée sans savoir si elle est bien dans la base de données du serveur.
Protocole Hybride
La technologie Pub/Sub et la technologie REST ont toutes deux leurs avantages et leurs inconvénients :
Avantages Pub/Sub :
- Transfert rapide des informations
- stockage automatique des messages
- gestion de la qualité de service
Inconvénient Pub/Sub :
- On ne peut pas faire d’action directe sur le message, on ne fait un traitement dessus que lorsqu'on l'a reçu.
- protocole mqtt, qui est bloqué par certains pare-feu
Avantages REST :
- protocole http(port 80) passe partout dans le monde
- on peut traiter le message directement sur le serveur
Inconvénient REST :
- On doit installer un serveur web, on doit gérer une base de données (ou XML, Json).
L'objectif du protocole hybride est de réaliser un système pub/sub tel que l'on ait :
- un transfert rapide des informations
- un stockage automatique des messages
- une gestion de la qualité de service
- le protocole http (port 80) de sorte à ce qu'il fonctionne partout dans le monde.
Pour cela, nous allons nous servir des Websockets.
MQTT sur Websocket
Le protocole Websocket est un protocole qui vise à développer un canal de communication web sur une connexion TCP.
Les objectifs de ce protocole étaient notamment de permettre au serveur l'envoi de données vers le client en mode push (sans que l'utilisateur n'ait à faire une requête).
Pour notre protocole hybride, l'idée serait d'ouvrir un canal de communication Websocket entre le broker et le client.
Lorsque l'on envoie le message mqtt au broker, on le place dans un paquet websocket puis on l'envoie au broker. Lorsque le serveur reçoit le paquet, il l'ouvre et traite le message Mqtt contenu comme il l'aurai fait avec un message mqtt "normal". On fait de même lorsque le broker envoie un message au client qui s'est abonné.
On peut l'illustrer de la façon suivante :
Ainsi puisque le protocole Websocket se sert du port 80, on conserve les avantages de la technologie pub/sub avec Mqtt tout en évitant le problème des pare-feu que l'on pouvait rencontrer avec le protocole Mqtt.