Developpement d'une application IoT avec Node + Socket.io

Je serai speaker ce soir lors du meetup organisé par la communauté Node.js Paris qui bénéficiera de la présence exceptionnelle d’Issac Roth, CEO de StrongLoop.

Dans le cadre de mes activités au sein de la Division DX de Microsoft France, j’ai eu l’occasion d’être impliqué à diverses reprises sur des projets de développement Node.js dans Azure. Pour partager mes retours d’expérience, j’ai donc prévu de présenter comment l’on pouvait utiliser Node pour implementer rapidement une application IoT.

Pourquoi avoir choisi un scénario Internet Of Things ?
Au-delà de sa dimension hype, avec l’explosion du nombre de devices (en 2018, 3 fois plus d’appareils connectés que d’habitants d’après une étude CISCO), ce sujet devrait être favorable à l’éclosion d’applications bâties sur Node. En effet, il faudra être en mesure de proposer une infrastructure backend scalable et hautement disponible. L’avènement du Cloud et du Big Data apporte un premier niveau de réponse, mais le choix d’un environnement de développement adapté sera également un élément clé de la réussite de ces futurs projets. Node apparaît alors comme une des technologies de référence pour le développement de ces services en raison de sa conception nativement asynchrone et évènementielle, de sa capacité à scaler et de la possibilité de réutiliser les compétences existantes en javascript.

J’ai donc revu et adapté le code que Julien Corioland et moi avions produit lors du dernier Azure Camp, de façon à présenter une solution avec un backend uniquement fondé sur Node.js. J’avais déjà investigué un certain nombre de points liés à l’utilisation de Node pour ce type de solution.

Voici l’architecture conceptuelle de cette application :

image

L’implémentation de ce scenario de bout en bout m’aura permis d’explorer plus en avant certains aspects, notamment la façon de gérer le CORS (Cross-Origin Resource Sharing) dans un serveur de sockets Node en capturant le domaine d’origine du client, en validant l’accès dans le cas où le browser fait la demande via la méthode “OPTIONS”, et en spécifiant que l’écoute sur les sockets se fait quelque soit le domaine d’origine du browser.

io = require('socket.io').listen(http, { origins: '*:*' }),

var origin = (request.headers.origin || "*");

if (request.method.toUpperCase() === "OPTIONS") {

response.writeHead(

"204",

"No Content",

{

"access-control-allow-origin": origin,

"access-control-allow-methods": "GET, POST, PUT, DELETE, OPTIONS",

"access-control-allow-headers": "content-type, accept, X-Requested-With",

"content-type": "text/html; charset=utf-8",

"access-control-max-age": 10,

"content-length": 0

}

);

return (response.end());

}

J’ai également pu étudier les possibilités qu’offraient les différentes implémentations de socketio sur d’autres environnements que Node :

Ces deux API correspondent à une implementation 0.9.17 de socket.io et ne sont pas alignées sur la version 1.0.X. Leur mode de programmation est similaire.

var endpoint = @"https://iotnodejshub.azurewebsites.net";

var extension_socketio = @"/socket.io";
var endpoint_full_url = endpoint + extension_socketio;

var socketIOClient = new SocketIOClient.WinRT.Client(endpoint_full_url);

socketIOClient.On("connect", async (fn) =>
{
if (socketIOClient.IsConnected)
{
//…
}
});
await _socketIOClient.ConnectAsync();

Enfin, j’ai pu tester l’utilisation d’Azure Notification Service depuis Node.

var azure = require("azure"),
notification = azure.createNotificationHubService( NOTIFICATION_HUB_PATH, NOTIFICATION_CONNECTION_STRING);
var toast = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<toast>" +
"<visual>" +
"<binding template=\"ToastText04\">" +
"<text id=\"1\">Alerte humidite</text>" +
"<text id=\"2\"> Derniere mesure : " + humidity + " %</text>" +
"</binding>" +
"</visual>" +
"</toast>";
notification.wns.send(null, toast, "wns/toast", 3, function (error) {
if (error) {
console.error(error);
}
});

La présentation est disponible ici.

J’ai publié l’application IoTNodejsWeatherMonitor sur GitHub à l’adresse suivante : https://github.com/stephgou/IoTNodejsWeatherMonitor