与SignalR共享ServiceStack ICacheClient

时间:2013-09-10 23:59:04

标签: c# dependency-injection servicestack signalr simple-injector

我正在尝试在ServiceStack OOB ICacheClient和SignalR Hub之间共享缓存中的元素,但是当我尝试在OnDisconnected事件中获取用户会话时,我收到以下错误

  

仅支持通过单身人士访问的ASP.NET请求

我在OnConnected事件中访问会话没有问题,到目前为止,这就是我所做的:

public class HubService:Hub
{
    private readonly IUserRepository _userRepository;
    private readonly ICacheClient _cacheClient;

    public HubService(IUserRepository userRepository,ICacheClient cacheClient)
    {
        _userRepository = userRepository;
        _cacheClient = cacheClient;
    }

    public override System.Threading.Tasks.Task OnConnected()
    {
        var session = _cacheClient.SessionAs<AuthUserSession>();
        //Some Code, but No error here
        return base.OnConnected();
    }

    public override System.Threading.Tasks.Task OnDisconnected()
    {
        var session = _cacheClient.SessionAs<AuthUserSession>();
        return base.OnDisconnected();
    }
}

我正在使用简单的注入器,我的ICacheClient注册为singleton:

 Container.RegisterSingle<ICacheClient>(()=>new MemoryCacheClient());

问题是如何在SS中注册请求作为单身人士?我在SignalR事件中缺少什么?

修改

我试图在SS中注释注册请求是因为如果有可能使用容器注册SS IHttpRequest并且由于异常消息将生活方式设置为单例,那么它似乎是httpContext和OnDisconnected事件

使IHttprequest为空

SS代码如下:

public static string GetSessionId(IHttpRequest httpReq = null)
{
    if (httpReq == null && HttpContext.Current == null)
        throw new NotImplementedException(OnlyAspNet); //message
        httpReq = httpReq ?? HttpContext.Current.Request.ToRequest();
        return httpReq.GetSessionId();
}

我要做的是使用ICacheClient存储已连接用户的列表,我只想在用户断开连接时从列表中删除connectionID。

修改 似乎根据danludwig post

  

“SignalR有一个有趣的事情......当客户端断开连接时   集线器(例如通过关闭他们的浏览器窗口),它将创建一个   Hub类的新实例,以便调用OnDisconnected()。   发生这种情况时,HttpContext.Current为null。因此,如果此Hub具有任何依赖于每个Web请求注册的依赖项,则可能会出现问题。“

上面的描述完全符合我的情况

1 个答案:

答案 0 :(得分:4)

我不是SingalR专家,但根据我的经验和简单的注入器,我不认为你可以在OnDisconnected期间获得Session(或者Request或HttpContext)。如果你考虑它就有意义了 - 当客户端断开与集线器的连接时,SignalR不再能够访问会话ID,没有请求,也没有与客户端的通信。 OnDisconnected基本上告诉你“在这里,用这个ConnectionId做一些事情,因为它所属的客户端已经消失了。”当然,用户可能会回来,然后在OnReconnected期间,您可以访问Web好东西(会话,请求等,只要您是IIS托管的)。

我遇到类似的问题,在这3个Hub连接事件中,获得一些simpleinjector依赖项以获得正确的生命周期范围。我想在每个http请求中注册1个依赖项,除了OnDisconnected之外,它还适用于所有内容。因此,我必须尽可能使用SI容器来使用http请求,但在OnDisconnected事件期间需要依赖时使用新的生命周期范围。如果您想阅读它,我会发布一篇描述我的经历的帖子here。祝你好运。