ID TECH
Contact
Tous les articles techniques

Article technique

Connectez-vous aux lecteurs de cartes USB avec des WebSockets

Vous pouvez connecter n'importe quel lecteur de cartes USB depuis n'importe quel navigateur web grâce aux WebSockets et à NodeJS. Cela vous permet d'effectuer des transactions EMV depuis un terminal virtuel. Découvrez comment ci-dessous.

La dernière fois, j'ai montré comment configurer la connectivité USB via JavaScript en utilisant NodeJS et un module appelé node-hid. Le résultat : nous avons pu accéder par programmation à des périphériques USB, en JavaScript, en seulement une soixantaine de lignes de code. Notre script gérait la détection et la connexion automatiques des périphériques, et nous fournissait un handle de périphérique permettant la lecture et l'écriture de données USB.

Tout cela est très bien, si votre seul besoin est d'accéder par programmation aux données USB depuis un script Node.

Mais que faire si vous souhaitez transmettre ces données à un autre processus ? Et si, par exemple, vous vouliez envoyer des données USB vers un navigateur web ? Ou les pousser vers un serveur ?

Aucun problème. C'est tout à fait possible, et même très simple !

Les WebSockets à la rescousse

Le protocole Websocket (spécification IETF ici) est l'un des standards Web les plus remarquablement utiles à avoir vu le jour depuis très, très longtemps. Et heureusement, il est pris en charge par tous les navigateurs modernes. De plus, il est accessible aux scripts Node. Ce qui signifie que votre code Node peut communiquer très facilement avec vos scripts de navigateur, à condition de créer une connexion socket qui fait le pont entre ces deux univers.

Côté Node, vous devrez ouvrir une console OS et exécuter npm install socket.io -g (une seule fois) pour installer le module socket.io , très largement utilisé et dont la popularité est amplement méritée. Une fois cette étape effectuée, vos scripts pourront appeler require("socket.io") pour tirer parti de la puissance remarquable de ce module. (Nous y reviendrons dans un instant.)

Côté navigateur, vous devez pointer vers socket.io.slim.js , afin que votre page web puisse recevoir des données via Websocket. (N'essayez pas d'utiliser l'API Websocket native du navigateur, car le module socket.io mentionné précédemment utilise son propre mécanisme de maintien de connexion, qui n'est pas reconnu par votre navigateur. Pour éviter tout conflit, utilisez le script côté client socket.io.slim.js. Avantage supplémentaire : ce script inclut des polyfills qui assurent la compatibilité Websocket avec les navigateurs plus anciens.) La façon la plus simple d'obtenir le script côté client est de le charger depuis un serveur de périphérie (CDN) en insérant l'extrait de code suivant dans votre page web :

Une fois ce script en place, votre page web est prête à se connecter aux sockets servis par votre propre serveur de sockets.

Mise en place des Websockets

Voyons comment configurer un serveur de sockets en mode loopback (c'est-à-dire sur ws://localhost). C'est d'une simplicité remarquable, et particulièrement pratique pour la communication inter-processus.

Vous aurez bien entendu besoin de Node, ainsi que du module socket.io (tel que décrit ci-dessus). Il vous faudra ensuite lancer Node et lui faire exécuter un script similaire au suivant :

Sans tenir compte des commentaires, nous n'avons affaire qu'à une trentaine de lignes de code. Concrètement, voici ce qui se passe : nous require('http')afin de pouvoir configurer une instance de serveur HTTP factice. Puis nous require('socket.io').listen(server) pour que le module socket.io puisse mettre à niveau les requêtes HTTP entrantes en connexions Websocket.

Par défaut, les connexions Websocket permettent une communication bidirectionnelle complète, basée sur des messages, entre les parties connectées. Toutefois, une communication point à point ne signifie pas que les messages sont automatiquement diffusés aux autres connexions. Pour activer la diffusion, nous enregistrons un écouteur d'événements personnalisé : on.('echo') un écouteur à la ligne 58, qui réémet les messages « echo » entrants vers toutes les connexions socket, sous la forme d'un nouveau message de type 'message'. La règle est donc la suivante : pour une messagerie point à point, utilisez le type d'événement 'message' ; en revanche, pour que le serveur socket transmette votre message à tous les écouteurs, utilisez le type de message 'echo'. (Il s'agit de notre propre convention, et non d'une contrainte imposée par socket.io.)

Dernière remarque importante : le code ci-dessus, tel quel, ne fait rien, car il s'agit d'une définition de classe. Vous devez instancier la classe au moment de l'exécution pour pouvoir l'utiliser. Mais c'est très simple. Les commentaires en tête du code expliquent comment utiliser la classe. Nous verrons également comment l'utiliser dans les prochains articles de blog.

Ne manquez pas les prochains articles de cette série : nous allons très bientôt réaliser des transactions sans contact sur une passerelle en production — le tout depuis le navigateur, en JavaScript ! Revenez nous voir prochainement !