4

我正在尝试在 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 被注册为单例:

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

问题是如何在 SS 中将请求注册为单例?SignalR 事件中我缺少什么?

编辑:

我试图解释 SS 中的注册请求是因为如果有可能使用容器注册 SS IHttpRequest 并由于异常消息将生活方式设置为单例,那么 OnDisconnected 事件似乎 httpContext 和 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 的帖子

“关于 SignalR 有一个有趣的事情......当客户端与集线器断开连接时(例如通过关闭其浏览器窗口),它将创建集线器类的新实例以调用 OnDisconnected()。当这种情况发生时, “

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

4

1 回答 1

4

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

在这 3 个集线器连接事件期间,我遇到了类似的问题,让一些简单的注入器依赖项具有正确的生命周期范围。我想为每个 http 请求注册 1 个依赖项,它适用于除 OnDisconnected 之外的所有内容。因此,我不得不在可能的情况下使 SI 容器使用 http 请求,但在 OnDisconnected 事件期间需要依赖项时使用新的生命周期范围。如果您愿意阅读它,我在这里有一篇文章描述了我的经历。祝你好运。

于 2013-09-11T10:09:04.243 回答