Push con SingalR

Últimamente se está oyendo hablar mucho de SignalR en los en tornos de ASP.Net y no es para menos.

Los programadores web estamos acostumbrados a hacer peticiones al servidor “Pull” para poder consultar cualquier cosa y en más de una ocasión hemos tenido que tirar de un timer en el cliente para que cada X-tiempo consulte un recurso del servidor e ir informando al usuario del progreso de una tarea o de los datos que se tienen que actualizar constantemente.

Para evitar esto podríamos utilizar a día de hoy varias opciones como la API de html5 WebSocket que está en fase borrador y ha tenido algún problema de seguridad, podemos utilizar el servidor Openfire con el protocolo XMPP o servidor Node.js con la librería Nowjs . Pero la ventaja que proporciona SignalR frente los otros es que esta especialmente diseñado para aprovechar las características de las aplicaciones ASP.NET MVC tanto el lado del servidor como la parte cliente.

Como empezar

Para empezar tenemos que instalar la librería que tenemos disponible desde Nuget.

Tienes que tener en cuenta que tiene dependencias con la librería JQuery .

El Servidor

En el servidor solo necesitamos una clase que implemente Hub y si queremos hacer una devolución al cliente solo tenemos que añadir una expresión dinámica a Clients que se resolverá en tiempo de ejecución.

public class NotificationHub : Hub
    {
public void Notificar(string valor)
        {
Clients.AddValor("Informamos al cliente");
        }
    }

El cliente

Recordar la dependencia con JQuery y además hay que poner una referencia a «/Signalr/Hubs» que es donde se crearan los scripts dinámicamente para las llamadas al servidor.

<script type="text/javascript">// <![CDATA[
src</span>="/Scripts/jquery-1.7.1.js" type="text/javascript">
// ]]></script>
<script type="text/javascript">// <![CDATA[
src</span>="/Scripts/jquery.signalR.js" type="text/javascript">
// ]]></script>
<script type="text/javascript">// <![CDATA[
src</span>="/Signalr/Hubs" type="text/javascript">
// ]]></script>

 

$.connection.hub.start();
var hub = $.connection.notificationHub;
hub.AddValor = function (valor) {
alert(valor);
    };

1. Abrimos la conexión con el servidor.
2. Inicializamos nuestro hub donde haremos las llamadas.
3. Definimos la función de devolución para actuar cuando el servidor nos informe.

Ya esta !!!!  Es súper sencillo !!!! 

EJEMPLO

Haré un pequeño ejemplo para que se vea toda su potencia en acción. Imaginaros un control de encuesta donde sea el servidor el que te informe que sus datos se han actualizado y solo permita votar una vez al usuario, toda la lógica estará en el servidor y no en la UI, de esta manera no mezclamos responsabilidades.
Utilizaré la librería jqplot.js para mostrar la gráfica de la encuesta en tiempo real.

Servidor

Primero crearé la parte del servidor donde estará la lógica de los votos.

public class NotificationHub : Hub
 {
public void Notificar( string valor)
     {
if (valor != null && Encuesta.Instance != null
&& Encuesta.Datos.ContainsKey(valor))
         {
var clientId = Context.ClientId;
if (Encuesta.Usuarios.Any(u => u == clientId))
             {
                 // El usuario ya ha votado no hay que actuar
                 // ni informar de actualizaciones
              }
else
         {
Encuesta.Usuarios.Add(clientId);
              Encuesta.Datos[valor]++;
var resultado = Encuesta.Datos.Keys.Select(
key => new List</pre>
()
<pre>
                    {
key, Encuesta.Datos[key]
}).ToList();

              // Informamos al cliente
Clients.AddValor(resultado);
          }
     }
  }
}

Esta clase controla si el usuario ya ha votado y si no lo añade a la lista para no permitir votar la próxima vez que llame el mismo cliente y como se puede observar, tenemos acceso al identificador del cliente para controlar quien es el que hace la llamada, pero además podemos acceder al dentity para hacer un seguimiento más exhaustivo del usuario y sus credenciales.

Luego si el voto es de un elemento correcto le incrementa el número de votos y retorna a todos los clientes conectados los nuevos datos de la encuesta actualizada.

El cliente llamara a Notificar(valor) para informar del voto y estará en espera que el servidor actualice los datos con AddValor(resultado).

Cliente

Tendremos una vista con varios radio buttons para seleccionar las opciones de la encuesta y un botón que lanzara la llamada al servidor con la selección del usuario.

$(function () {
inicializarEncuesta();
$("#btnSendNotificacion").click(function () {
var voto = $('input:radio:checked').val();
            hub.notificar(voto);
        });
        $.connection.hub.start();
var hub = $.connection.notificationHub;
hub.AddValor = function (valor) {
$.jqplot('chart1', [valor], chartOption()).replot();
        };
    });

Si el servidor devuelve nuevos datos “AddValor” entonces repintaremos el gráfico con la nueva información.

De esta manera todos los usuarios conectados a la encuesta reciben las actualizaciones en tiempo real.

Conclusión

SignalR es un Framework potente y fácil de utilizar que nos permite mantener conexiones abiertas con el servidor de ASP.NET.
Con este tipo de librerías podemos empezar a realizar aplicaciones realmente colaborativas y en tiempo real, donde se definen mejor las responsabilidades gracias a las llamadas Push y nos ayuda a no agregar lógica de negocios en nuestras UI.

7 comentarios en “Push con SingalR

  1. Oriol dijo:

    Hola Marc
    Eetoy desarrolando una aplicación desktop que pretende tener conectadas varios miles de usuarios concurrentes, conexiones persistentes. Sabes que limitación tiene el Signal R?

    Gracias
    Oriol

  2. Puedo usar signalr en una aplicación de negocio, cual realiza insert, update, delete y select a una base de datos. Es que lo ejemplos que observo siempre los basan en chat. Saludos.

  3. ohtm4 dijo:

    Puedo utilizar signalr para crear una aplicación que consulte, edite, elimine e inserte registros en base de datos y que estos registros se vean en tiempo real. Saludos. Hay algún ejemplo al respecto.

  4. Martin Navarrete dijo:

    Que tal quiero hacer un componente o proyecto en el cual se muestre por USUARIO la actualizacion de sus mensajes desde servidor. Es decir tipo Facebook que te marca quiza un globo de la cantidad de mensajes nuevos desde la ultima vez que revisaste.

Replica a Martin Navarrete Cancelar la respuesta