2015-11-16 5 views
8

Ich möchte Benutzerinformationen für die Lebensdauer einer SignalR-Anfrage statisch speichern. Ich habe dies in WebAPI mit HttpContext.Current.Items getan, aber das ist nicht in SignalR vorhanden.Pro-Request statische Daten in Signal

Ich weiß, dass ThreadStatic nicht funktioniert, da ein SignalR-Thread zwischen mehreren Anfragen geteilt werden kann.

Als Referenz Ich bin Hosting es innerhalb IIS und die neueste Version von SignalR mit (2.2.0)

+0

Die meisten Lösungen für diese erfordern eine andere, hartnäckigere Klasse oder ein Wörterbuch in Not. Haben Sie eine 'Dictionary ' versucht, die ConnectionIDs auf alle Daten aufzeichnet, die Sie verfolgen möchten? Fügen Sie Personen in 'OnConnect' hinzu, entfernen Sie sie in' OnDisconnect'. –

Antwort

0

Dies ist sicherlich für die Beantwortung dieser Frage ist sehr spät und vielleicht haben Sie schon etwas dafür herausgefunden. Dies ist nur ein Versuch, meine Gedanken zu diesem Problem zu teilen.

Zunächst können Sie die Authentifizierung für SignalR aktivieren, und dann können Sie Context.User.xxx in Ihren Hub-Methoden verwenden.

Für authentication for all hubs ermöglichen können Sie etwas tun:

public partial class Startup { 
    public void Configuration(IAppBuilder app) { 
     app.MapSignalR(); 
     GlobalHost.HubPipeline.RequireAuthentication(); 
    } 
} 

Sobald Sie tun, dass Sie immer noch Ihre übliche Authentifizierung Pipeline verwenden können, um Ihre Anfragen zu authentifizieren, und diejenigen Informationen werden Hub Methoden über Context.User Eigenschaft geliefert werden . Unten ist ein Beispiel von here.

public async Task JoinRoom(string roomName) 
{ 
    await Groups.Add(Context.ConnectionId, roomName); 
    Clients.Group(roomName).addChatMessage(Context.User.Identity.Name + " joined."); 
} 

mit diesem Zusammen können Sie pro Benutzer Daten in einem Out-of-Memory-Speicher halten (so dass es skalieren kann), wie Redis Cache oder etwas ähnliches.

Alternativ können Sie auch HubPipelineModule erweitern und eine custom one erstellen, um eine genauere Steuerung von Ereignissen zu ermöglichen.

public class LoggingPipelineModule : HubPipelineModule 
{ 
    protected override bool OnBeforeIncoming(IHubIncomingInvokerContext context) 
    { 
     return base.OnBeforeIncoming(context); 
    } 
    protected override bool OnBeforeOutgoing(IHubOutgoingInvokerContext context) 
    { 
     return base.OnBeforeOutgoing(context); 
    } 
} 

public void Configuration(IAppBuilder app) 
{ 
    GlobalHost.HubPipeline.AddModule(new LoggingPipelineModule()); 
    app.MapSignalR(); 
} 

Hoffe das hilft. Es wäre auch interessant zu wissen, wie Sie mit dem Problem umgegangen sind.