c# - Cómo usar SignalR para notificar a los clientes web de ASP.NET MVC 3 que las tareas de MSMQ se completaron
wcf asp.net-mvc-3 (1)
Si entiendo correctamente, necesita una forma de asociar una tarea a un usuario / cliente determinado para que pueda decirle al cliente cuando su tarea se ha completado.
La documentación de la API de SignalR me dice que puede llamar a los métodos JS para clientes específicos según la identificación del cliente ( https://github.com/SignalR/SignalR/wiki/SignalR-Client ). En teoría podrías hacer algo como:
- Almacene el ID de cliente utilizado por SignalR como parte de los metadatos de la tarea:
- Poner en cola la tarea como de costumbre.
- Cuando la tarea se procesa y se despeja de la cola:
- Actualiza tu base de datos con el estado.
- Usando la identificación del cliente almacenada como parte de esa tarea, use SignalR para enviar una notificación a ese cliente:
Debería poder recuperar la conexión que su cliente está usando 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 se asignó esta conexión y el cliente usó esa conexión para iniciar la solicitud de procesamiento de datos en primer lugar. Su "barra de navegación principal" tiene el JS que inició la conexión con el ProcessNotificationsConnection
final ProcessNotificationsConnection
que asignó anteriormente.
EDITAR: 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);
}
}
¿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 utiliza autenticación de formularios), una base de datos de SQL Server 2008 y un servicio MSMQ WCF (alojado en WAS) para procesar los datos? El entorno de ejecución consta de IIS 7.5 que se ejecuta en Windows Server 2008 R2 Standard Edition.
Solo he jugado con las muestras y no tengo un conocimiento extenso de SignalR.
Aquí hay algunos antecedentes
La aplicación web acepta datos del usuario y los agrega a una tabla. Luego llama a una operación unidireccional (con la clave de la base de datos) del servicio WCF para procesar los datos (una tarea). La aplicación web regresa a una página que le informa al usuario que los datos se enviaron y se les notificará cuando se realice el procesamiento. El usuario puede ver una página de "índice" y ver qué tareas se completaron, fallaron o están en curso. Pueden continuar enviando más tareas (que son independientes 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 desde milisegundos hasta varios minutos. Cuando termina de procesar los datos, el registro se actualiza con el estado correspondiente (error o error) y resultados.
La mayoría de las veces, el servicio WCF no realiza ningún procesamiento, sin embargo, cuando lo hace, los usuarios generalmente desean saber cuándo se realiza tan pronto como sea 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 que el usuario les notifique 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 lo desean.
Usando jQuery, sondeo el servidor para los cambios. La acción del controlador verifica si hay algún proceso que haya sido modificado (completado o fallado) y, de lo contrario, los espera en un par de segundos y verifica nuevamente sin regresar al cliente. Para evitar un tiempo de espera en el cliente, regresará después de 30 segundos si no hubo cambios. El script jQuery espera un momento y vuelve a intentarlo.
Los problemas
El rendimiento se degrada con cada usuario que ve una página. No hay necesidad de que hagan nada en particular. Hemos notado que el uso de la memoria de Firefox 7+ y Safari aumenta con el tiempo.
Utilizando SignalR
Espero que el cambio a SignalR pueda reducir el sondeo y, por lo tanto, reducir los requisitos de recursos, especialmente si nada ha cambiado la tarea en la base de datos. Tengo problemas para obtener el servicio WCF para notificar a los clientes que se realiza con el procesamiento de una tarea dado que utiliza la autenticación basada en formularios.
Al hacer esta pregunta, espero que alguien me dé una mejor idea de cómo rediseñarán mi esquema de notificación utilizando SignalR, en todo caso.