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.

 

 
1 public class NotificationHub : Hub
2 {
3 public void Notificar(string valor)
4 {
5 Clients.AddValor("Informamos al cliente");
6 }
7 }

 

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.

 

 

1 <script type="text/javascript">// <![CDATA[
2 src</span>="/Scripts/jquery-1.7.1.js" type="text/javascript">
3 // ]]></script>
4 <script type="text/javascript">// <![CDATA[
5 src</span>="/Scripts/jquery.signalR.js" type="text/javascript">
6 // ]]></script>
7 <script type="text/javascript">// <![CDATA[
8 src</span>="/Signalr/Hubs" type="text/javascript">
9 // ]]></script>

 

 

1 $.connection.hub.start();
2 var hub = $.connection.notificationHub;
3 hub.AddValor = function (valor) {
4 alert(valor);
5 };

 

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.

  

01 public class NotificationHub : Hub
02 {
03 public void Notificar( string valor)
04 {
05 if (valor != null && Encuesta.Instance != null
06 && Encuesta.Datos.ContainsKey(valor))
07 {
08 var clientId = Context.ClientId;
09 if (Encuesta.Usuarios.Any(u => u == clientId))
10 {
11 // El usuario ya ha votado no hay que actuar
12 // ni informar de actualizaciones
13 }
14 else
15 {
16 Encuesta.Usuarios.Add(clientId);
17 Encuesta.Datos[valor]++;
18 var resultado = Encuesta.Datos.Keys.Select(
19 key => new List</pre>
20 ()
21 <pre>
22 {
23 key, Encuesta.Datos[key]
24 }).ToList();
25
26 // Informamos al cliente
27 Clients.AddValor(resultado);
28 }
29 }
30 }
31 }

 

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.

 

 

01 $(function () {
02 inicializarEncuesta();
03 $("#btnSendNotificacion").click(function () {
04 var voto = $('input:radio:checked').val();
05 hub.notificar(voto);
06 });
07 $.connection.hub.start();
08 var hub = $.connection.notificationHub;
09 hub.AddValor = function (valor) {
10 $.jqplot('chart1', [valor], chartOption()).replot();
11 };
12 });

 

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.

 

Cross-Posting: http://mrubino.net 

 

 

2 comentarios en “Push con SingalR”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *