Otra de las novedades que trae HTML5 es la de los famosos websockets. El protocolo HTTP funciona de tal manera que no existe una conexión fija entre el cliente y el servidor; el navegador y el servidor se están continuamente lanzando piedras con mensajes, y a veces para simular que la conexión es permanente (una sesión) se acompaña de alguna marca como una cookie. Los websockets nos dan la posiblidad de establecer una conexión fija entre cliente y servidor como la que hay en un IRC o en los servicios de juegos; en el navegador podemos conectarnos a un servidor de websockets con una especie de Sockets ultrasimplificados y por supuesto orientados a eventos.

Esto nos abre puertas a muchas aplicaciones, desde información en tiempo real, el obvio chat, juegos HTML5 multijugador, etc... . Una pregunta que en buena lógica atormentaría a cualquier sysadmin con canas que oye hablar de esto por primera vez es pero chacho ¿qué servidor va a aguantar ahora la tralla de conexiones permanentes? Un servidorcillo web con su apache y su php si encima le exiges mantener conexiones permanentes reventará. Ahí es donde entran en juego tecnologías como Node.js, que con un solo hilo y con eventos te aguantan lo que sea.

Websockets 'puros'

En teoría los navegadores debieran tener soporte para un objeto javascript llamado WebSocket y un programa cliente podría tener este aspecto:


    
        
        
        pure WebSockets
        
        
        

    
    

        
        

Hello Web Sockets - PURE

Pure Web Sockets sample


Pero al igual que pasaba con el IndexedDB, el soporte para WebSockets todavía no está plenamente extendido (quizás mientras escribo este texto entre paréntesis la cosa esté cambiando). ¿Tenemos alguna opción, alguna librería que nos unifique la programación de websockets de forma transparente? Existe y se llama:

Socket.io, websockets que funcionan en cualquier navegador
Logo gafapastero de socket.io

Socket.io sería como el one wrapper to rule them all. Si te descargas el zip desde (cómo no) su repositorio github te toparás con algo peculiar. NO HAY una librería js para el lado cliente. Lo que te encuentras es un conjunto de librerías listas para montar un servidor Node.js que usa socket.io. Lo que haces es crear una especie de servidor web/websocket. Lo único que hace la parte web es servirte una página html destinada a contener el código del cliente websocket. ¿Y la librería js de socket.io? Te la genera tu servidor Node.js+socket.io al vuelo según las necesidades del navegador ¡¡¡Crema máxima!!!. El servidor aparte de servir esa página lo que tiene luego no son más que handlers según el tipo de mensaje que le llegue. Es decir, tanto el cliente como el server pueden mandar contenido precedido de una cadena, y eso nos sirve para poder dirigir el control a distintos handlers, muy bien pensado para evitar un mega switch-case. Aquí lo puedes ver:

var app = require('http').createServer(handler)
  , io = require('socket.io').listen(app)
  , fs = require('fs')

app.listen(8666);

function handler (req, res) {
  // We send back the client interface
  // with socket.io dynamic library
  fs.readFile(__dirname + '/websockets.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading websockets.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

/**
* onConnection controller.
* we set a kind of event depending on emit parameters.
* when client send emit('event666') the handler will be socket.on('event666')
*/
io.sockets.on('connection', function (socket) {

  socket.on('myname', function (data) {
    console.log('Received from client:' + data.name);
    socket.emit('fromserver', { msg: 'ok, hello ' + data.name });
  });

  socket.on('fromclient', function (data) {
    console.log('Received from client:' + data);
      socket.emit('fromserver', { msg: 'ok, message received: ' + data.msg });
  });

});

Debo decir que para iniciar el server he tenido que instalarme algún paquete que faltaba, pero luego ya sin problemas.

El cliente

¿Y qué aspecto tiene el cliente? Bien, en lugar de utilizar la librería estándar WebSocket, lo que haces es usar socket.io y el método emit. Y el resto sigue siendo igual de simple. En mi caso tenía un navegador iceweasel más desfasado que los pantalones de campana (quizás mientras escribo este texto entre paréntesis las estanterías de los bershka se están llenando otra vez de esos pantalones). Pero gracias a socket.io y su fallback de tecnologías (intento una, luego otra, luego otra) he podido conectarme y comunicarme con el servidor.


    
        
        
        WebSockets
        
        
        
        

    
    

        
        

Hello Web Sockets

Web Sockets sample


Et voila!

prueba de concepto

Obviamente esto no era más que una prueba de concepto, pero ha merecido la pena para conocer socket.io. Funciona, la web trae muchos ejemplos listos para usar (con express también), y vamos está muy bien montado. Hasta que HTML5 se estabilice, será indispensable usar librerías como esta.

Y sí, el título de ...and Websockets for all es por Metallica, porque algunos somos tan raros que no estamos obsesionados con el Master of Pupppets.