2011-11-17 7 views
16

come si potrebbe usare SignalR per implementare le notifiche in un sistema di .NET 4.0, che consiste in un 3 applicazione ASP.NET MVC (che utilizza le forme autenticazione), database SQL Server 2008 e un servizio WCM MSMQ (ospitato in WAS) per elaborare i dati? L'ambiente di runtime è costituito da IIS 7.5 in esecuzione su Windows Server 2008 R2 Standard Edition.Come utilizzare SignalR per notificare i clienti web da ASP.NET MVC 3 che i compiti sono stati completati MSMQ

ho giocato solo con i campioni e non hanno una conoscenza approfondita di SignalR.

Ecco alcuni retroscena

L'applicazione web accetta dati da parte dell'utente e lo aggiunge a una tabella. Quindi chiama un'operazione a senso unico (con la chiave di database) del servizio WCF per elaborare i dati (un'attività). L'applicazione web ritorna a una pagina che comunica all'utente che i dati sono stati inviati e che saranno avvisati al termine dell'elaborazione. L'utente può guardare una pagina "indice" e vedere quali attività sono completate, fallite o in corso. Possono continuare a inviare più compiti (che è indipendente dai dati precedenti). Possono chiudere il browser e tornare più tardi.

Il servizio WCF basato MSMQ legge il record dal database ed elabora i dati. Ciò può richiedere qualsiasi cosa, da millisecondi a diversi minuti. Al termine dell'elaborazione dei dati, il record viene aggiornato con lo stato corrispondente (errore o errore) e risultati.

maggior parte del tempo, il servizio WCF non esegue alcuna elaborazione, ma quando lo fa, gli utenti in genere vogliono sapere quando il suo fare il più presto possibile. L'utente utilizzerà comunque altre parti dell'applicazione Web anche se non ha i dati che devono essere elaborati dal servizio WCF.

Questo è ciò che ho fatto

Nella barra di navigazione principale, ho un indicatore (simile a Facebook o Google+) per l'utente per notificare quando lo stato delle attività è cambiato. Quando cliccano su di esso, ottengono un riepilogo di ciò che è stato fatto e possono quindi visualizzare i risultati, se lo desiderano.

Utilizzando jQuery, eseguo il polling sul server per le modifiche. L'azione del controllore controlla se ci sono processi che sono stati modificati (completati o falliti) e restituirli altrimenti attende un paio di secondi e controlla di nuovo senza tornare al client. Per evitare un timeout sul client, esso ritornerà dopo 30 secondi se non ci sono state modifiche. Lo script jQuery attende un po 'di tempo e ci riprova.

I problemi

prestazioni si riducono con ogni utente che visualizza una pagina. Non c'è bisogno che facciano qualcosa in particolare. Abbiamo notato che l'utilizzo della memoria di Firefox 7+ e Safari aumenta nel tempo.

Utilizzando SignalR

Spero che il passaggio a SignalR può ridurre polling e quindi ridurre i requisiti delle risorse, soprattutto se non è cambiato nulla compito saggio nel database. Ho difficoltà a ottenere il servizio WCF per notificare ai client che è stato eseguito con l'elaborazione di un'attività, dato che utilizza l'autenticazione basata su moduli.

Con questa domanda, spero che qualcuno mi darà una migliore comprensione di come si ridisegnare il mio sistema di notifica utilizzando SignalR, se non del tutto.

+0

Qualsiasi suggerimento per [questo] (http://stackoverflow.com/q/34090045/2404470) – xameeramir

risposta

8

Se ho capito correttamente, è necessario un modo per associare un'attività a un determinato utente/client in modo da poter dire al client quando il loro compito è stato completato.

Documentazione API SignalR mi dice che è possibile chiamare i metodi JS per client specifici in base all'ID client (https://github.com/SignalR/SignalR/wiki/SignalR-Client). In teoria si potrebbe fare qualcosa di simile:

  1. memorizzare l'ID client utilizzato da SignalR come parte dei metadati compito:
  2. coda l'attività come normale.
  3. Quando l'attività viene elaborato e de-coda:
    • aggiornare il database con lo stato.
    • utilizzando l'ID cliente memorizzati come parte di questo compito, utilizzare SignalR per inviare quel cliente una notifica:

si dovrebbe essere in grado di recuperare la connessione che il client utilizzi e inviare loro un messaggio :

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

questo presuppone mappata questa connessione e il client utilizzato che il collegamento per avviare la richiesta di trattamento dei dati, in primo luogo. La "barra di navigazione principale" ha il JS che ha avviato la connessione all'endpoint ProcessNotificationsConnection mappato in precedenza.

EDIT: Da 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

L'API client non-JS non mi permette di inviare un gruppo specifico o un client a un messaggio. Di conseguenza, non esiste alcun valore per inviarlo al processo in background. Tuttavia, rispedisco di nuovo l'ID al sito Web, che ottiene l'"id" del "proprietario" e invia una notifica al gruppo SignalR con tale "id". Mentre gli utenti si connettono e si disconnettono, aggiungo i client al gruppo. – bloudraak

+0

Se lavori all'interno di un hub lo fa. Vedi risposta modificata. – PabloC

+0

la tua risposta ha funzionato, tuttavia, alla fine ho deciso di abbandonare SignalR per una soluzione personalizzata che supporti in modo trasparente la sicurezza. Pertanto, un utente può solo inviare notifiche agli utenti autorizzati a vedere tali messaggi. Quella richiesta non è mai stata parte della domanda originale, quindi ho contrassegnato la tua come risposta. – bloudraak

Problemi correlati