2012-09-18 14 views
16

Capisco perché SignalR non ti dà access to the HttpContext. Tuttavia, questo è abbastanza problematico per noi. Lasciatemi spiegare:SignalR e HttpContext/Session

La nostra applicazione è un'applicazione multi-titolare in cui l'utente sceglie l'ambiente durante l'accesso. In pratica registra ConnectionStringName in HttpSession. Nel nostro Hub SignalR, dobbiamo accedere al database su Disconnect. Ma questo non è possibile perché non abbiamo HttpContext a questo punto e non possiamo determinare l'ambiente in cui scrivere.

Qualcuno può fornirci un suggerimento su come risolvere questo problema? Siamo un po 'bloccati su questo.

MODIFICA: punto bonus se la soluzione funziona in un ambiente con bilanciamento del carico.

+0

Stai ancora cercando una soluzione qui? –

+0

Abbiamo implementato la funzione in un modo completamente diverso. – Lodewijk

+1

@Lodewijk, potresti condividere il tuo modo diverso? Sono nella stessa situazione. –

risposta

0

È possibile utilizzare qualcosa come un dizionario per tenere traccia del ConnectionId dell'utente quando si connettono. Anche l'utilizzo di SQL Server per memorizzare lo stato sessione può essere d'aiuto: http://support.microsoft.com/kb/317604

SignalR ti dà accesso a User.Identity.Name che puoi utilizzare per tracciare quando viene attivato il disoconnect().

+0

Purtroppo, le informazioni sull'utente non sono disponibili: "così come l'utente e i cookie di HubContext non verranno popolati." (https://github.com/SignalR/SignalR/wiki/Hubs) – Lodewijk

+0

Inoltre, siamo in un ambiente con bilanciamento del carico, quindi la disconnessione potrebbe finire sull'altro server in cui il dizionario non è popolato. – Lodewijk

+0

Ho esaminato il codice precedente e Context.User.Identity.Name mostra l'utente attualmente connesso. Se l'ambiente è bilanciato, dovresti forse guardare redis per SignalR. https://github.com/SignalR/SignalR/wiki/SignalR-with-Redis-Running-on-a-Windows-Azure-Virtual-Macchina – Steve

0

Il fatto che sia necessaria la soluzione per lavorare su un ambiente con bilanciamento del carico impone il fatto che è necessario memorizzare la stringa di connessione in qualcosa di diverso da Session. Un archivio di valori-chiave (come si implementa non importa) dove la chiave è ConnectionId (le uniche informazioni disponibili su disconnect) e il valore è la stringa di connessione. Puoi continuare a utilizzare Session in qualsiasi altro posto, se vuoi, ma penso che dovresti spostare l'intera applicazione per scrivere e leggere da lì, almeno per quelle informazioni.

+0

Lo stato della sessione non è un problema in un ambiente con bilanciamento del carico e non esiste da almeno un decennio. –

+0

Leggi meglio la domanda prima di votare, HttpContext non è disponibile con SignalR (o almeno non era in quel momento), e con quella sessione – Wasp

+1

In realtà HttpContext e HttpContext.Current sono entrambi disponibili ed è solo Session che è null. – Dave

7

Hi ha avuto un problema simile a quello che mi serviva per identificare i visitatori non autenticati della mia applicazione per personalizzare le loro richieste all'hub SignalR.

L'ho risolto accedendo a "HttpContext.Current.Request.AnonymousId". AnonymousId esegue il mapping su un record temporaneo in un'entità di sessione auto-implementata in un database SQL, emulando essenzialmente una sessione supportata da database.

Ecco alcuni documentazione rilevante nel caso in cui si desidera personalizzare l'AnonymousId, o inizializzare il database-entry: http://msdn.microsoft.com/en-us/library/system.web.httprequest.anonymousid.aspx

Inoltre, si dovrebbe essere in grado di accedere al contesto in OnDisconnected() in questo modo: Context.Request .GetHttpContext().

Spero che questo aiuti.

20

Questa è una vecchia domanda, ma sto lasciando la mia risposta solo nel caso in cui sia utile a chiunque là fuori.

Poiché l'hub si estende Microsoft.AspNet.SignalR.Hub ha accesso al contesto proprietà di tipo HubCallerContext

Questa struttura espone un sacco di informazioni da parte del chiamante:

  • connectionId
  • intestazioni
  • QueryString
  • Richiesta
  • Cookies
  • utente

Nella mia soluzione io uso il nome utente memorizzato in Context.User.Identity.Name come una chiave nella mia chiave/valore negozio (Redis nel mio caso) per tenere traccia di tutte le connessioni che un utente ha.

È possibile ignorare OnConnnect e OnDisconnect per mantenere l'elenco delle connessioni associate all'utente. Puoi anche archiviare qualsiasi altra cosa con gli id ​​delle connessioni (le stringhe di connessione dell'utente, nel tuo caso).

+3

Sfortunatamente il caching basato sul nome utente non funziona se l'utente ha più sessioni aperte ... – Dave

+1

Ti dispiacerebbe elaborare? –

+0

Ho avuto un problema simile qui: http://stackoverflow.com/questions/27729113/null-exception-on-httpcontext-current-request-cookies-when-firing-signalr-method. Questo thread mi ha salvato dal tirarmi fuori i capelli. Ho risolto il problema ma non capisco veramente il problema. Se qualcuno potesse capovolgere e darmi una risposta solida sarebbe fantastico! Odio andare avanti senza comprenderlo appieno. –