La noticia del día en cuanto a desarrollo web sin duda ha sido la implementación de Web Sockets en Chromium. una tecnología de comunicación bidireccional para aplicaciones web.

Los Web Sockets son un borrador del W3C que, mediante una conexión TCP, permiten realizar fácilmente un Server Push, es decir, una petición iniciada desde el servidor central. Es un cambio notable en la programación web, hasta ahora dirigida por peticiones iniciadas desde el cliente.

Veamos un ejemplo del código del lado del cliente:

if ("WebSocket" in window) {
  var ws = new WebSocket("ws://example.com/service");
  ws.onopen = function() {
    // Se conecta el websocket. Puedes enviar datos con el método send()
    ws.send("mensaje a enviar"); ....
  };
  ws.onmessage = function (evt) { var received_msg = evt.data; ... };
  ws.onclose = function() { // se cierra el websocket. };
} else {
  // el navegador no soportaWebSocket.
}

Ridícultamente sencillo, ¿verdad? :) Como se puede observar en la URI de la petición, funciona mediante un protocolo distinto al HTTP (ws://example.com/service), el web socket protocol. Por tanto el servidor debe estar capacitado para manejar dichas peticiones. Con fines experimentales, Google ha creado pywebsocket, un módulo del servidor web Apache que implementa dicho protocolo (Dejo para otro post el colgar un howto para ver cómo instalarlo y ejecutar un ejemplo funcional).

Las ventajas son evidentes: Supongamos un chat. Un usuario accede y dice “hola”. Empleando tecnología AJAX, deberá enviarse una petición HTTP completa, posiblemente superando 1KB para sólo cuatro caracteres. Multipliquemos esto por miles de conexiones simultáneas con millones de usuarios diarios (Como le ocurre a Facebook): Tendríamos un problema de ancho de banda. Con este nuevo protocolo, las peticiones son mínimas :)

Uno de los apartados más criticados ha sido la necesidad de relegar el socket a una conexión TCP, impidiendo aprovechar otros protocolos como UDP o RUDP. Además, y pese a ir sobre TCP, funciona sobre otro protocolo a nivel de aplicación, por lo que no sería posible acceder desde el navegador a, por ejemplo, un servidor IRC (Salvo que se haga através de otro servidor que haga de proxy).

Comet

No se puede hablar de WebSockets sin mencionar otra tecnología. En el año 2006 Alex Russell definió y acuñó lo que hoy conocemos como Comet: Un patrón que define un método para implementar Server Push desde cualquier navegador. Si bien no fue el que lo creó, pues algunos sitios como el chat de Google en Gmail ya utilizaban técnicas similares.

Los principales métodos para lograr Comet en el navegador son éstos:

  • Streaming- Consiste en mantener una una única conexión persistente desde el navegador al servidor. Cada vez que el servidor envía un nuevo evento, el navegador lo interpreta. Hay dos técnicas:
    1. IFrame oculto – Se utiliza un IFrame oculto en el que el servidor va escribiendo, cada vez que lo desea, porciones de código javascript. Es efectivo gracias a que los navegadores ejecutan los documentos HTML de forma secuencial. Sin embargo trae problemas en el motor de renderizado KHTML, pues no se comparte javascript entre distintos documentos.
    2. XMLHTTPRequest – En 1995, Netscape Navigator añadió una funcionalidad llamada “server push” que permite peticiones XHR “multipart” mediante el tipo mime multipart/x-mixed-replace. De ese modo se puede utilizar una petición XHR como canal de streaming. Sin embargo sólo es soportado por el motor Gecko, no así por otros grandes players como Trident o Webkit.
  • Long polling en AJAX – Las soluciones anteriores causan efectos negativos en los navegadores modernos. Por eso, muchas aplicaciones optan por una estrategia de long polling, funcional en todos los navegadores que soportan XHR.Esta técnica se basa en el uso de AJAX, realizando una petición que no es cerrada hasta que el servidor contesta. Una vez se recibe respuesta, comienza de nuevo el sondeo.
    • XMLHttpRequest long polling – Funciona como la mayoría de aplicaciones AJAX: Se lanza una petición al servidor, y no se cierra la conexión hasta que se recibe la respuesta. Una vez recibida, automáticamente se lanza otra nueva petición.
    • Script tag long polling – Si bien los métodos anteriores funcionan entre subdominios, no lo hacen entre distintos dominios de segundo nivel debido a protecciones anti XSS de los navegadores. Gracias a que la etiqueta script, a diferencia de un IFrame o de una petición XHR, puede apuntar a distintos dominios de segundo nivel, se logra solucionar este problema.

Especial mención respecto a Comet merece el protocolo Bayeux, y la implementación CometD de Dojo Foundation. Utilizando el paradigma Comet, han diseñado todo un protocolo de red que, a diferencia de “web socket protocol”, funciona generalmente sobre HTTP, permitiendo ser ejecutado en cualquier navegador moderno. Como API del lador del cliente se puede utiliar indistintamente su framework javascript Dojo, o JQuery. Eso sí, el lado del servidor debe saber interpretar también el protocolo Bayeux, por tanto es necesario instalar unas determinadas bibliotecas, actualmente disponibles para servidores Java.

Otras implementaciones de Sockets

Por supuesto aquí no acaba la cosa. Algunos plugins permiten ejecutar sockets, como por ejemplo el objeto Socket de Adobe Flash que permite enviar flujos binarios. Por supuesto Silverlight y Java mediante applets también permiten realizarlo.

El uso de Flash como proxy para conexiones bidireccionales, por ejemplo, puede resultar muy atractivo, pues está presente en prácticamente todos los navegadores. Sin embargo, y en mi opinión, siempre es mejor emplear tecnologías estándar, como los Web Sockets del W3C, en lugar de soluciones propietarias.

¿Y ahora qué?

Las comunicaciones bidireccionales reales están más cerca. ¿Qué cambia esto? Para los desarrolladores significa un método más versátil y aun más sencillo que XHR para nuestras páginas web. Por supuesto también es un ahorro en ancho de banda (Aunque bendito el programador web que emprenda y deba enfrentarse a problemas de ancho de banda).

¿Y para los usuarios? Junto con otras tecnologias, los Web Sockets abren muchas puertas de cara al futuro. Por ejemplo, con O3D o WebGL, sockets y <audio> se podrán desarrollar videojuegos en HTML si necesidad de Flash. Aun nos falta, por ejemplo, soporte para el micrófono, la webcam, o datagramas binarios, pero tiempo al tiemo :) ¡Estén atentos!