SignalR: envío de datos en tiempo real desde el servidor

by fnunez 10. marzo 2012 11:44

SignalR es una librería de código abierto que permite el envío asíncrono y en tiempo real de datos desde un servidor web a los clientes o navegadores conectados al mismo. Se trata de un framework desarrollado por el equipo de ASP.NET y su uso es realmente sencillo como veremos en este artículo, en el que vamos a desarrollar una aplicación de chat o mensajería instantánea utilizando esta librería.

Introducción

La transferencia de información en la Web se basa en el envío de peticiones HTTP entre el navegador y el servidor. El navegador o cliente envía una solicitud, el servidor la procesa, envía la información y cierra la conexión. Estas peticiones pueden devolver una página web completa o parte de la misma, si se utilizan técnicas AJAX. Pero en ambos casos, una vez enviados los datos al cliente, el servidor cerrará la conexión.

Esta característica de las transacciones HTTP complica el desarrollo de aplicaciones en las que es necesario que el servidor se comunique en tiempo real con los clientes, para informarles de un evento o transferir información sin que estos la soliciten. Lo más habitual en estos casos es desarrollar mecanismos de polling en el código cliente, que consisten en interrogar periódicamente al servidor para ver si hay información nueva o se ha producido un evento determinado. Desgraciadamente, cuando el número de clientes es muy elevado esta opción no es viable por el incremento en el consumo de ancho de banda y carga de trabajo en el servidor.

Conexión persistente entre cliente y servidor

A la espera de la llegada definitiva de HTML 5 y los WebSockets, la alternativa a las técnicas de polling en el cliente son las tecnologías COMET, y en particular aquellas que combinan AJAX y Long Polling, mecanismo que permite emular conexiones persistentes empleando peticiones HTTP.

Básicamente, su funcionamiento consiste en lo siguiente: el servidor en lugar de responder inmediatamente a una petición del cliente, la guarda y envía una respuesta cuando tiene datos disponibles o transcurre un tiempo determinado. A continuación el cliente vuelve a establecer otra conexión en espera de nueva información. De esta manera, encadenando conexiones de larga duración, se consigue emular una conexión persistente entre servidor y cliente que podrá ser utilizada por el servidor para enviar información en tiempo real a los navegadores clientes.

SignalR

Como comentábamos al principio, SignalR es una librería desarrollada por el equipo de ASP.NET, en concreto por David Fowler y Damian Edwars, que permite llevar a cabo conexiones persistentes entre servidor y cliente de manera sencilla. Se trata de una abstracción que oculta la complejidad de estos mecanismos y permite trabajar con distintos modos de “transporte”, como WebSockets o Long Polling, para el envío bidireccional de datos entre servidor y clientes.

SignalR ofrece dos modos de trabajo: uno de bajo nivel mediante la clase SignalR.PersistentConnection, y otro de alto nivel basado en la clase SignalR.Hub que nos permitirá crear conexiones persistentes en una aplicación.NET con muy pocas líneas de código. Este último será el que utilizaremos para desarrollar una sencilla aplicación ASP.NET de mensajería instantánea entre los clientes conectados al servidor.

Instalación

La instalación de SignalR es realmente fácil si tenemos instalada la extensión del gestor de paquetes NuGet en Visual Studio 2010. Bastará con seguir los siguientes pasos:

  1. Desde el menú Archivo seleccionamos la opción Nuevo Proyecto. En el apartado Web elegimos la opción Aplicación web vacía de ASP.NET.
  2. Una vez creado el proyecto, abriremos la consola de NuGet desde el menú Herramientas -> Library Package Manager -> Package Manager Console.
  3. En la consola escribiremos el siguiente comando: Install-Package SignalR. Esta instrucción descargará e instalará en el proyecto todos los componentes necesarios para utilizar SignalR.
  4. SignalR trabaja con JSON, motivo por el que es recomendable instalar la librería json2.js, sobre todo si vamos a trabajar con navegadores web antiguos. Para instalar este componente ejecutaremos el siguiente comando en la consola de NuGet: Install-Package json2

Una vez hecho esto tendremos la librería SignalR instalada y lista para su uso en nuestro proyecto ASP.NET.

Nota: la librería SignalR 0.4 disponible en el momento en el que se escribió este artículo presentaba errores de ejecución al referenciar a una versión de Newtonsoft.Json diferente a la instalada por NuGet. Para corregir este error es necesario desinstalar la versión 4.0.8 e instalar y hacer referencia a la versión 4.0.7 de Newtonsoft.Json en el proyecto.

Servidor

El siguiente paso es crear una clase servidor cuya función será recibir los mensajes de los clientes y distribuirlos a los navegadores conectados. Para ello, desde el explorador de soluciones nos situamos sobre el nombre de nuestro proyecto y mediante el botón derecho del ratón seleccionamos la opción Agregar -> Clase.

El código que debemos escribir en esta clase será:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using SignalR.Hubs;

namespace ejemploSignalR
{
   public class Chat : Hub
   {
      public void enviar(string mensaje)
      {
         string usuario = Caller.nombre;
         Clients.recibir(usuario + " dice: " + mensaje);
      }
    }
}

Como podemos observar se trata de una clase bastante sencilla que hereda de SignalR.Hub y cuenta con un único método denominado enviar. Este método recibe como parámetro el mensaje de texto enviado por el navegador y lo distribuye al resto de clientes invocando al método recibir. Este método estará presente en el código de la página que ejecutarán los navegadores conectados como veremos en el siguiente paso.

Cliente

A continuación añadiremos la página ASP.NET que ejecutarán los navegadores que se conecten a nuestra aplicación de chat. Para ello nos situamos otra vez en el explorador de soluciones y mediante el botón derecho seleccionamos Añadir -> Nuevo elemento -> WebForms. En el nombre de la página escribiremos default.aspx.

El código HTML de nuestra página ASPX será el siguiente:

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
	<title>prueba SignalR</title>
	<script type="text/javascript" src="Scripts/jquery-1.6.4.min.js"></script>
	<script type="text/javascript" src="Scripts/json2.min.js"></script>
	<script type="text/javascript" src="Scripts/jquery.signalR.min.js"></script>
	<script type="text/javascript" src="<%= ResolveClientUrl("~/signalr/hubs") %>"></script>
	<script type="text/javascript">
		$("document").ready(function () {

			// Creamos el proxy (hub)
			var chat = $.connection.chat;
			// Función que invocará el servidor para enviar los mensajes al cliente.
			chat.recibir = function (mensaje) {
				$("#mensajes").append("<li>" + mensaje + "</li>");
			};

			//Evento del botón "Enviar". Ejecuta la función "enviar" que transfiere el mensaje al servidor
			$("#enviar").click(function () {
				if ($("#textomensaje").val() != "") {
					var mensaje = $("#textomensaje").val();
					chat.nombre = $("#usuario").val();
					chat.enviar(mensaje);
					$("#textomensaje").val("");
				}

			});

			// Iniciamos la conexión persistente con el servidor
			$.connection.hub.start();

		});
	</script>
</head>
<body>
	<form id="form1" runat="server">
		<div style="border:1px solid #000;width:645px;height:336px;margin-bottom:5px;">
			<ul id="mensajes"></ul>
		</div>
		<div>
			<input id="usuario" type="text" style="width:95px;" />
			<input id="textomensaje" type="text" style="width: 482px;" />
			<input id="enviar" type="button" value="enviar" />
		</div>
	</form>
</body>
</html>

Como podemos ver, todo lo que necesitamos es incluir las librerías jQuery, JSON y SignalR en el orden adecuado y unas pocas líneas de código Javascript para establecer la conexión y definir las funciones para el envío y recepción de mensajes. No son necesarios mecanismos de polling ni nada parecido: cuando un usuario escribe un mensaje desde su navegador el servidor lo distribuirá al resto de usuarios llamando a la función recibir de cada navegador conectado.

Si ejecutamos el proyecto en Visual Studio y copiamos la URL en un par de pestañas de nuestro navegador podremos comprobar como funciona la aplicación de chat SignalR. 

Conclusión

SignalR es una excelente herramienta que facilita enormemente el desarrollo de sitios web interactivos con actualizaciones de datos en tiempo real. Se trata todavía de un proyecto en desarrollo pero su facilidad de uso y las características que ya ofrece su versión preliminar lo hacen altamente recomendable para este tipo de aplicaciones web.

A continuación incluyo algunos enlaces para profundizar más en las características de SignalR.

Acerca de este blog

Soy ingeniero de software. En este blog recopilo artículos, notas y enlaces que considero interesantes.

Archivo