¿Qué transporte está usando nuestro cliente con SignalR?
Introducción
Este sábado pasado, en MsCoders Madrid hicimos un evento de 9:00 a 14:30 meramente técnico y práctico donde la gente tenía la posibilidad de elegir dos sesiones de 6 posibles, divididas en 3 tracks.
Lo único que debían traer era su portátil y ganas, muchas ganas de aprender, compartir y pasar un buen rato.
En mi caso, estuve llevando una de las sesiones, la dedicada a SignalR y cuyo título era “Juegos en tiempo real con SignalR y HTML 5”. Lejos de extenderme respecto a mis impresiones, todas positivas, lo que más me gustó es que no había entradas libres para la sesión, lo cual mostraba el interés de la misma, aunque para ser honesto, creo que hubo gente que se movió de sala o que no pudo finalmente venir porque había algún hueco en la sala.
El caso es que durante la sesión, quise demostrar como SignalR decide qué transporte utilizar dependiendo del cliente y servidor que tengamos (dependiendo de los extremos), pero al final no pude demostrarlo por culpa de un despiste mío (mea culpa, a veces soy un poco despistado). Eso hizo que no me funcionara bien en la demostración cuando lo tenía listo y preparado, pero bueno, lo importante es demostrarlo y eso es lo que quiero hacer aquí, para los que quieran saber como hacerlo.
SignalR y tranportes
Para que SignalR actúe en tiempo real, es necesario que trabaje sobre un transporte adecuado.
Esta adecuación como vimos el sábado (los que pudieron acudir al encuentro) no siempre es tan bonita como la pintan, y es que los extremos “mandan”, aunque podemos forzarlo si bien nos podemos encontrar con desagradables resultados.
Lo importante. SignalR trabaja o puede trabajar con 4 tipos de transportes diferentes.
Dos transportes de HTML5: WebSocket y Server Send Events.
Dos transportes Comet: Forever Frame y Ajax Long Polling.
SignalR intentará siempre que pueda, utilizar WebSockets, pero tal y como vimos no siempre es posible.
Lo mejor de todo es que SignalR hará por nosotros el trabajo de resolver que tipo de transporte utilizar, lo que nos simplifica mucho las tareas de gestión creando esa capa de abstracción que nos evita perder el tiempo con controles, gestión, etc de transporte.
Para demostrar esto, vamos a basarnos en Internet Explorer, aunque podría utilizar más navegadores Web o clientes diferentes. El hecho de basarme en Internet Explorer es porque alguna de sus versiones soporta un tipo de transporte y otras no, y es un ejemplo ideal para demostrar este comportamiento.
Concretamente y para demostrar esto, utilizaremos Internet Explorer 10 en un servidor que soporta WebSocket. Es decir, Internet Explorer 10 soportará WebSocket también.
Y posteriormente, haremos lo mismo en el mismo servidor que soporta WebSocket, pero con Internet Explorer 8, el cual no soporta WebSocket.
Así podremos ver como SignalR gestiona por nosotros el transporte a utilizar.
Internet Explorer y WebSocket
Para llevar a cabo esto, vamos a modificar el cliente, que en mi caso será una página Web, y justo después de establecer la conexión, voy a habilitar las trazas.
$.connection.hub.logging = true;
Agregando esta línea de código y ejecutando nuestra aplicación, veremos cuál es el transporte que vamos a utilizar.
Para Internet Explorer 10, el resultado que obtenemos en la consola es el que se indica en la siguiente imagen (WebSocket):
En el caso de utilizar Internet Explorer 8, el resultado de la consola es diferente (LongPolling):
Finalmente, voy a poner un diagrama sobre la decisión de qué transporte utilizar en SignalR y que me he encontrado en un foro (http://stackoverflow.com/questions/16983630/how-does-signalr-decide-which-transport-method-to-be-used) por si a alguien le viene bien:
Espero que ayude a comprender un poco más como se establece el transporte en SignalR.