Publicación técnica
Conéctate a lectores de tarjetas USB con Websockets
Puedes conectarte a cualquier lector de tarjetas USB desde cualquier navegador web utilizando Websockets y NodeJS. Lo que significa que puedes realizar transacciones EMV desde un Terminal Virtual. ¡Descubre cómo a continuación!
La última vez, mostré cómo configurar la conectividad USB mediante JavaScript utilizando NodeJS y un módulo llamado node-hid. El resultado fue que pudimos obtener acceso programático a dispositivos USB, desde JavaScript, con apenas unas 75 líneas de código. Nuestro script implementaba la detección y conexión automática de dispositivos, y nos proporcionaba un manejador de dispositivo con el que leer y escribir datos USB.
Todo lo cual está muy bien, si lo único que necesitas es acceso programático a los datos USB desde dentro de un script de Node.
Pero ¿y si quieres comunicar esos datos a otro proceso? ¿Y si (por ejemplo) quieres enviar datos USB a un navegador web? ¿O subirlos a un servidor?
Sin problema. Puedes hacerlo. ¡Es muy fácil!
WEBSOCKETS AL RESCATE
El protocolo Websocket (especificación IETF aquí) es uno de los estándares web más asombrosamente útiles que han aparecido en mucho, mucho tiempo. Y, por suerte, está implementado por todos los navegadores modernos. Además, está disponible para los scripts de Node. Lo que significa que tu código de Node puede comunicarse con los scripts de tu navegador con bastante facilidad, basta con crear una conexión de socket que tienda un puente entre ambos mundos.
Por el lado de Node, vas a tener que abrir una consola del sistema operativo y ejecutar npm install socket.io -g (una sola vez) para instalar el muy utilizado y justificadamente popular módulo socket.io . Después de hacer esto, tus scripts podrán llamar a require("socket.io") para aprovechar la increíble potencia de ese módulo. (Sobre lo cual hablaremos enseguida.)
Por el lado del navegador, debes apuntar al script socket.io.slim.js , para que tu página web pueda consumir datos de Websocket. (No intentes usar la API estándar de Websocket del navegador para esto, porque el módulo socket.io mencionado utiliza su propio esquema de keep-alive que tu navegador no conoce. Para evitar conflictos, usa el script del lado del cliente socket.io.slim.js. Como ventaja adicional, el script incluye polyfills que proporcionan compatibilidad con Websocket a los navegadores más antiguos.) La forma más sencilla de obtener el script del lado del cliente es descargarlo desde un servidor de borde (CDN) incluyendo el siguiente fragmento en tu página web:
Con ese script en su sitio, tu página web está lista para conectarse a los sockets servidos por tu propio servidor de sockets.
SIRVIENDO WEBSOCKETS
Hablemos de cómo configurar un servidor de sockets en modo loopback (es decir, en ws://localhost). Es increíblemente sencillo y enormemente útil para la comunicación entre procesos.
Necesitas Node, por supuesto, y necesitas el módulo socket.io (como se ha descrito antes). Después debes ejecutar Node y hacer que corra un script como el siguiente:
Sin contar los comentarios, estamos hablando de solo unas 30 líneas de código. Conceptualmente, lo que ocurre es que require('http')para poder crear una instancia ficticia de servidor HTTP. Luego hacemos require('socket.io').listen(server) para que el módulo socket.io pueda actualizar las peticiones HTTP entrantes a conexiones Websocket.
De manera predeterminada, las conexiones Websocket permiten una comunicación punto a punto, full-duplex y basada en mensajes entre las partes conectadas. Pero punto a punto no significa que los mensajes se difundan automáticamente a otras conexiones. Para habilitar la difusión, registramos un escuchador de eventos personalizado, el on.('echo') en la línea 58, que reemite los mensajes "echo" entrantes a todas las conexiones de sockets, como un nuevo mensaje de tipo 'message'. Por tanto, la regla aquí es: para realizar mensajería punto a punto, usa el tipo de evento 'message', pero para asegurarte de que el servidor de sockets reenvía tu mensaje a todos los escuchadores, usa el tipo de mensaje 'echo'. (Esto es una convención nuestra, por cierto, no algo impuesto por socket.io.)
Lo último que hay que tener en cuenta es que el código anterior, por sí solo, no hace nada, porque es una definición de clase. Tienes que instanciar la clase en tiempo de ejecución para poder usarla. Pero eso es facilísimo. Los comentarios al inicio del código explican cómo usar la clase. Además, veremos cómo utilizarla en próximas entradas del blog.
No te pierdas las próximas entradas de esta serie, ¡porque en breve estaremos realizando transacciones sin contacto contra una pasarela real, todo desde el navegador y con JavaScript! ¡Vuelve pronto!
