Signalr 中的每个请求静态数据

Per-Request static data in Signalr

我想在 SignalR 请求的生命周期内静态存储用户信息。我已经在 WebAPI 中使用 HttpContext.Current.Items 这样做了,但在 SignalR 中不存在。

我知道 ThreadStatic 不起作用,因为 SignalR 线程可以在多个请求之间共享。

作为参考,我将其托管在 IIS 中并使用最新版本的 SignalR (2.2.0)

现在回答这个问题肯定已经很晚了,也许你已经想出了一些办法。这只是尝试分享我对这个问题的看法。

因此,首先,您可以为 SignalR 启用身份验证,然后您可以在集线器方法中使用 Context.User.xxx

要启用 authentication for all hubs,您可以这样做:

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

完成后,您仍然可以使用常用的身份验证管道来验证您的请求,这些信息将通过 Context.User 属性 提供给 Hub 方法。下面是 here.

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

除此之外,您还可以在内存不足的存储中维护每个用户的数据(以便它可以横向扩展),例如 Redis 缓存或类似的东西。

或者作为替代方法,您还可以扩展 HubPipelineModule, and create a custom one 以对事件进行更精细的控制。

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();
}

希望这对您有所帮助。也很想知道您是如何处理这个问题的。