Faire dialoguer des objets avec MQTT

L’Internet des objets

Le sujet d’aujourd’hui est bien à la mode. Il y a beaucoup de hype autour de ce terme. Mais qu’est ce que c’est réellement ? Prenons la définition de whatis :

The Internet of Things (IoT) is a scenario in which objects, animals or people are provided with unique identifiers and the ability to transfer data over a network without requiring human-to-human or human-to-computer interaction. IoT has evolved from the convergence of wireless technologies, micro-electromechanical systems (MEMS) and the Internet.

D’après cette définition, l’IoT (Internet of things) est la possibilité d’avoir sa machine à laver branché au net. Idéal pour recevoir sur son smartphone un message pour indiquer que les caleçons sont propres. Cool.

En vrai, qui l’utilise ?

Bien entendu, il y a des utilisations plus sérieuse. La voiture qui contacte automatiquement les secours en cas d’accident. Le controle de la température et de l’humidité dans une serre. Le suivi des animaux dans une ferme. Etc.

Tous ces modules sont différents d’un point de vue du design, du nombre et du genre des capteurs, poids, taille, etc. Chaque module a ses propres besoins mais une contrainte revient assez souvent. Ils sont disséminé à travers le paysage et doivent fonctionner dans des conditions souvent difficiles. L’autonomie, la qualité de la réception, ou la quantité de données à transférer sont les principales difficultés quand on construit ce genre de module.

Pourquoi MQTT ?

Prenons le plus petit message envoyé par HTTP.

  • Header TCP; 20 bytes
  • Header IP: 20 bytes
  • Data: 1 byte

On se retrouve à envoyer au minimum 41 bytes pour un message. Prenons un module connecté par GSM avec une carte SIM limitant le traffic à 5Mo par mois (cas réél rencontré récemment), le nombre de message transféré sera très limité.

Prenons maintenant le même message envoyé par MQTT.

  • Message: 2 bytes

Desuite, il y a beaucoup moins de limitations. Prenons ensuite en compte la consomation avec le pourcentage de la batterie utilisée pour envoyer un message durant une expérience (source) ;

  • 0.01709% pour HTTP
  • 0.00010% pour MQTT

Là encore,  on voit bien l’intérêt de limiter le transfert de données.

 Comment ça marche ?

Le protocole en lui-même est assez simple. Connect, subscribe, publish. On publit des messages sur un topic dans un broker. D’autres personnes écoutent ce qui est publié et reçoivent le message.

Il y a plusieurs implémentations de MQTT, dans à peu près tous les langages (Ok, peut être pas en brainfuck). Je vais me baser sur PAHO pour Java.

	
<dependency>
  <groupId>org.eclipse.paho</groupId>
  <artifactId>mqtt-client</artifactId>
  <version>0.2.1</version>
</dependency>

Voilà l’implémentation la plus basique.

	private MqttClient mqttClient;
	
	public void connectToBroker(String clientId) throws Exception {
		final MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
		mqttClient = new MqttClient("tcp://iot.eclipse.org:1883", clientId);
		mqttClient.setCallback(this);
		mqttClient.connect(mqttConnectOptions);
	}
	
	public void subscribe(String topic) throws Exception {
		mqttClient.subscribe(topic, 0);
	}
	
	public void publish(String topic, String message) throws Exception {
		final MqttMessage mqttMessage = new MqttMessage(message.getBytes());
		MqttDeliveryToken mqttDeliveryToken = mqttClient.getTopic(topic).publish(mqttMessage);
		mqttDeliveryToken.waitForCompletion();
		Thread.sleep(100);
	}
	
	public void connectionLost(Throwable arg0) {
	}

	public void deliveryComplete(IMqttDeliveryToken arg0) {
	}

	public void messageArrived(String arg0, MqttMessage message) throws Exception {
		System.out.println(new String(message.getPayload()));
	}
	
	public static void main(String[] args) throws Exception {
		FullMqttPoc poc = new FullMqttPoc();
		poc.connectToBroker("publisher");
		poc.subscribe("topicPocMqtt");
		poc.publish("topicPocMqtt", "ceci est mon message");
	}

Tout d’abord, le broker. Pour cet exemple, j’ai utilisé le broker en libre accès fourni par la fondation Eclipse à l’adresse tcp://iot.eclipse.org:1883. Une large palette de broker est disponible pour de vrais projets comme Mosquitto ou HiveMQ. La connection se fait sans identifiants, mais une version sécurisé est disponible également. Pour notre exemple, seul un clientId est nécessaire, celui-ci devant être unique sur le broker.

La suite se fait par publish/subscribe. Dans notre exemple, un seul processus joue les deux rôles. La console affichera dont juste “ceci est mon message”. Un exemple plus complet est disponible ici avec deux processus distincts.

Leave a Reply

Your email address will not be published. Required fields are marked *