2011-11-17 33 views
16

¿Cómo se usaría SignalR para implementar notificaciones en un sistema .NET 4.0 que consiste en una aplicación ASP.NET MVC 3 (que usa formularios autenticación), la base de datos SQL Server 2008 y un servicio MSMQ WCF (alojado en WAS) para procesar los datos? El entorno de tiempo de ejecución consiste en IIS 7.5 que se ejecuta en Windows Server 2008 R2 Standard Edition.Cómo utilizar SignalR para notificar a los clientes web desde ASP.NET MVC 3 que las tareas de MSMQ se completaron

Solo he jugado con las muestras y no tengo un amplio conocimiento de SignalR.

Aquí es un poco de fondo

La aplicación web acepta datos del usuario y lo añade a una mesa. A continuación, llama a una operación unidireccional (con la clave de base de datos) del servicio WCF para procesar los datos (una tarea). La aplicación web regresa a una página donde se le informa al usuario que los datos fueron enviados y se les notificará cuando finalice el procesamiento. El usuario puede mirar una página de "índice" y ver qué tareas se completan, fallan o están en progreso. Pueden continuar enviando más tareas (que es independiente de los datos anteriores). Pueden cerrar su navegador y volver más tarde.

El servicio WCF basado en MSMQ lee el registro de la base de datos y procesa los datos. Esto puede llevar de milisegundos a varios minutos. Cuando termina de procesar los datos, el registro se actualiza con el estado correspondiente (error o falla) y los resultados.

La mayoría de las veces, el servicio WCF no realiza ningún procesamiento, sin embargo, cuando lo hace, los usuarios generalmente quieren saber cuándo se realiza lo antes posible. El usuario seguirá utilizando otras partes de la aplicación web, incluso si no tienen datos para ser procesados ​​por el Servicio WCF.

Esto es lo que he hecho

En la barra de navegación principal, tengo un indicador (similar a Facebook o Google+) para el usuario para notificarles cuando el estado de las tareas ha cambiado. Cuando hacen clic en él, obtienen un resumen de lo que se hizo y luego pueden ver los resultados si así lo desean.

Utilizando jQuery, consulto los cambios en el servidor. La acción del controlador comprueba si hay algún proceso que se modificó (completado o fallido) y lo devuelve; de ​​lo contrario, espera un par de segundos y vuelve a verificar sin volver al cliente. Para evitar un tiempo de espera en el cliente, regresará después de 30 segundos si no hubo cambios. La secuencia de comandos jQuery espera un momento y vuelve a intentarlo.

Los problemas

rendimiento se degrada con cada usuario que visita una página. No es necesario que hagan nada en particular. Hemos notado que el uso de memoria de Firefox 7+ y Safari aumenta con el tiempo.

Usando SignalR

Estoy esperando que el cambio a SignalR puede reducir de votación y así reducir las necesidades de recursos, especialmente si nada hubiera cambiado tarea sabio en la base de datos. Tengo problemas para que el servicio de WCF notifique a los clientes que ha finalizado el procesamiento de una tarea, dado que utiliza autenticación basada en formularios.

Al hacer esta pregunta, espero que alguien me de una mejor idea de cómo rediseñarán mi esquema de notificación con SignalR, si es que lo hace.

+0

Cualquier sugerencia para [esto] (http://stackoverflow.com/q/34090045/2404470) – xameeramir

Respuesta

8

Si entiendo correctamente, necesita una forma de asociar una tarea a un usuario/cliente determinado para que pueda decirle al cliente cuando se haya completado su tarea.

La documentación de SignalR API me dice que puede llamar a los métodos de JS para clientes específicos basados ​​en la identificación del cliente (https://github.com/SignalR/SignalR/wiki/SignalR-Client). En teoría, usted podría hacer algo como:

  1. almacenar el ID de cliente utilizado por SignalR como parte de los metadatos tarea:
  2. cola de la tarea como algo normal.
  3. Cuando la tarea se procesa y se pone en cola-DE:
    • actualización de su base de datos con el estado.
    • utilizando el ID de cliente almacenada como parte de esa tarea, utilice SignalR para enviar ese cliente una notificación:

usted debería ser capaz de recuperar la conexión que el cliente está utilizando y enviarles un mensaje :

string clientId = processedMessage.ClientId //Stored when you originally queued it. 
IConnection connection = Connection.GetConnection<ProcessNotificationsConnection>(); 
connection.Send(clientId, "Your data was processed"); 

esto supone que asignó esta conexión y el cliente usa esa conexión para iniciar la solicitud de procesamiento de datos en el primer lugar. Su "barra de navegación principal" tiene el JS que inició la conexión al punto final ProcessNotificationsConnection que asignó anteriormente.

EDIT: De https://github.com/SignalR/SignalR/wiki/Hubs

public class MyHub : Hub 
{ 
    public void Send(string data) 
    { 
    // Invoke a method on the calling client 
    Caller.addMessage(data); 

    // Similar to above, the more verbose way 
    Clients[Context.ClientId].addMessage(data); 

    // Invoke addMessage on all clients in group foo 
    Clients["foo"].addMessage(data); 
    } 
} 
+0

La API del cliente no JS no me permite envíe un mensaje específico a un grupo o cliente específico. Como resultado, no hay ningún valor para enviarlo al proceso en segundo plano. Sin embargo, devuelvo el id al sitio web, que luego obtiene el "id" del "propietario" y envía una notificación al grupo SignalR con ese "id". A medida que los usuarios se conectan y desconectan, agrego los clientes al grupo. – bloudraak

+0

Si trabaja en un concentrador, sí lo hace. Ver respuesta modificada. – PabloC

+0

su respuesta funcionó, sin embargo, al final decidí dejar caer SignalR para obtener una solución personalizada que sea compatible con la seguridad de forma transparente. Por lo tanto, un usuario solo puede enviar notificaciones a usuarios autorizados a ver dichos mensajes. Ese requisito nunca formó parte de la pregunta original, por lo que marqué el tuyo como respuesta. – bloudraak

Cuestiones relacionadas