miércoles, 4 de junio de 2014

SignalR ASP.NET









En muchas ocasiones hemos tenido el problema de tratar de recibir información del servidor desde un cliente en tiempo real, aplicando muchas veces métodos que no son los apropiados para realizar dichas operaciones. 
 Actualmente existen varias alternativas para realizar dicha comunicación en tiempo real, aplicando diferentes tecnologías, (websockets, Socket I/O, node.js) las cuales realizan esta tarea de forma más eficiente, por el lado de .NET contamos con signalR.

¿Qué es signalR?

SignaR es una abstracción de websockets para el uso con .net desde el servidor, este conjunto de librerías nos permite realizar implementaciones en tiempo real, esta implementación nos permite establecer un canal de comunicación en donde el servidor también puede ejecutar métodos en el cliente.
Una comunicación sin una implementación en tiempo real implica que el cliente siempre está preguntando al servidor que debe realizar, o si hay información que mostrar en un periodo determinado, ejemplo:
Un cliente pregunta al servidor si tiene mensajes nuevos
While(true){

server.GetAllMessages();

}
En este caso el método GetAllMessages es consultado de forma periódica aun si no existen mensajes para mostrar, además el ciclo o frecuencia de preguntas no siempre es constante, por carga que se pueda tener en el cliente, y llamados innecesarios al servidor.

  
Cómo funciona 


SignalR provee un API que hace uso de RPC (remote procedure calling)  el cual permite al servidor o a nuestro backend hacer llamado de procedimientos, o métodos de nuestro cliente.
  
En este ejemplo existen dos funciones, una del lado del servidor (FuncionServidor), y otra del lado del cliente (FuncionCliente), para este caso si el servidor tiene nuevos mensajes, el servidor ejecuta el método del cliente funcionCliente, y envía el mensaje correspondiente.
En el caso que el browser soporte websockets, la comunicación se establece por este medio, si no el api de signalR determina cual es el canal de comunicación para realizar la comunicación
Como vemos el servidor es quien ejecuta dicho método, y no el cliente en un periodo determinado, con base en este principio veamos un ejemplo en .NET.
Para revisar el ejemplo tengamos claros los siguientes conceptos:
Hub: es la clase que implementaremos del API,  cada uno de los métodos que creemos en esta podrán ser invocados desde nuestro cliente
Métodos Dinámicos: a partir del framework 4 existen y en signalR estos métodos corresponden a los nombres de las funciones en el cliente que serán ejecutadas, para más información de objetos y métodos dinámicos:
Ejemplo

Configuración del cliente

Vamos a realizar la configuración del cliente, en donde en primera instancia debemos tener las librerías necesarias para hacer uso del API

En nuestro ejemplo usamos jquery 1.10.2 min, y jquery.signalR – 2.0.0, esta plantilla puede ser generada y descargada de forma automática si descargamos los paquetes necesarios en visualestudio, si quisiéramos hacer uso de signalR desde cualquier parte solo importamos el js de signalR.

En nuestro archivo html importamos los correspondientes scripts

Preparamos los controles en el html un input de tipo texto para capturar el mensaje, un botón para enviar el mensaje, uno de tipo hidden para capturar el nombre del usuario, y una lista en donde almacenaremos los mensajes que envie el servidor

Para nuestro ejemplo, debemos tener en cuenta que se debe llamar una clase en el servidor, y un método, en este caso la clase en el backend se llama ChatHub, y tiene un método que se llama MetodoServidor
1. Declarar el proxy para referenciar a nuestro servidor, como vemos chatHub es nuestra clase en el servidor
var chat = $.connection.chatHub;
2. definimos la función que ejecutara el backend cuando tenga mensajes nuevos, es decir la función que ejecutara en el cliente
chat.client.MensajeCliente = function (name, message) {
var Nombre = $('<div />').text(name).html();
var Mensaje = $('<div />').text(message).html();
$('#Mensajes').append('<li><strong>' + Nombre
+ '</strong>:&nbsp;&nbsp;' + Mensaje + '</li>');
};
Como vemos chat.client hacen parte del api de signalR o más bien del js jquery.signalR – 2.0.0
Esta función recibe dos parámetros, nombre y mensaje, y ese nombre MensajeCliente es el ejecutado como método dinámico desde el servidor


3. iniciamos la conexión con nuestro servidor, cuando la conexión se halla establecido, agregamos el evento click al botón enviar mensaje, el cual realiza el envió del mensaje llamando al método del servidor MetodoServidor El cual hace parte de nuestra clase ChatHub en el backend.
  
$.connection.hub.start().done(function () {
$('#btnEnviarMensaje').click(function () {                                        chat.server.MetodoServidor($('#NombreCliente').val(), $('#txtmensaje').val());
$('#txtmensaje').val('').focus();
});
});


Configuración del servidor 
El servidor debe tener las siguientes referencias

De estas remarcamos
Microsoft.ASPNet.SignalR.COre

Microsoft.Owin

Owin

Si tenemos nuestros paquetes instalados, visualestudio nos permite crear un proyecto  con clases de tipo Hub, y este agrega de forma directa las referencias

Como vimos en el punto 1, se realizaba una instancia en js de nuestro hub y de los métodos que se ejecutarían en el servidor, para esto debemos crear una clase que herede de Hub y tenga las siguientes características
using System;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace SignalRChat
{
public class ChatHub : Hub
{
public void MetodoServidor(string name, string message)
{
Clients.All.MensajeCliente(name, message);
}
}
}
Hacemos importación de los paquetes de signalR,
Nuestra clase chatHub debe heredar de Hub
En este punto todos los métodos que creemos en esta clase, pueden ser accedidos desde los clientes mediante signalR con el js  jquery.signalR – 2.0.0
Este mismo nombre si nos detenemos a revisar, es el ejecutado por el javascript en el punto 3 chat.server.MetodoServidor, y el servidor responde a cada uno de los clientes con el método dinamico MensajeCliente el cual es de tipo dinámico debido a que no conocemos las funciones en el cliente, el objeto Clients, posee una cantidad de opciones para envió de mensajes los cuales están en:
Cada vez que un cliente ejecute MetodoServidor, el ejecutara en el cliente MensajeCLiente el cual está definido en el punto 2


Definimos la clase de configuración
using Microsoft.Owin;

using Owin;

[assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}
Y con esto podemos verificar que nuestra aplicación funcione.
Les dejo el link con la documentación correspondiente
y el código de ejemplo para este documento
https://dl.dropboxusercontent.com/u/4632636/signalrchat.7z



 

No hay comentarios:

Publicar un comentario