在ServiceStack插件中获取会话上下文

时间:2016-01-31 18:23:00

标签: multithreading session authentication plugins servicestack

杰米斯!首先,如果我把时间花在这个目标上,我想道歉。我们有一个基于Service 4.0.34的解决方案,它具有自定义类型的用户会话和RedisCacheClient。

我们要做的主要想法是在另一项服务中记录登录。它是有效的,但有时(并非总是,但经常)我们在一个用户会话的同时(最多毫秒)在日志中获得了大量登录记录。我们认为,这可能是由于服务的多线程特性,并决定使用队列进行日志请求(用于限制双打)。 在主配置模块中,我创建了一个方法,它只是一个发送者:

using (var redisPublisher = new RedisClient("localhost:6379"))
{
redisPublisher.PublishMessage(channelName, now);
}

另外,我在插件中写了一个接收器:

ThreadPool.QueueUserWorkItem(x =>
            {
                var redisFactory = new PooledRedisClientManager("localhost:6379");

                using (var client = redisFactory.GetClient())
                using (var subscription = client.CreateSubscription())
                {
                    subscription.OnMessage = (channel, msg) =>
                    {
                        var session = cacheClient.GetAll<string>(new string[] { "id", "userAuthName", "licenseInfoLastSend" });
                        //AuthUserSession curSession = appHost.GetCacheClient().SessionAs<ChicagoUserSession>();
                    };
                    subscription.SubscribeToChannelsMatching(String.Format("{0}_*", LocatorProductId)); //blocks thread
                }
            });

所以,我正确地收到了消息,但是我无法获得当前的会话上下文。是否可以在插件模块中获得会话?能否请你帮忙 ?

提前致谢!

1 个答案:

答案 0 :(得分:0)

会话与当前HTTP请求绑定,因为会话为identified by the Session Cookies,因此只能在HTTP请求的上下文中解析它们,因此您需要访问IRequest才能够使用GetSession()扩展方法解析会话,例如:

var session = req.GetSession();

内部ServiceStack IRequest在请求过滤器或服务,Razor视图等中的base.Request属性中可用。access the IRequest outside of ServiceStack还有多种方法,例如:

IHttpRequest httpReq = aspCtx.ToRequest(); //HttpContext
IHttpRequest httpReq = aspReq.ToRequest(); //MVC HttpRequestBase
IHttpRequest httpReq = listenerCtx.ToRequest(); //HttpListenerContext

在ASP.NET主机中,您可以通过单例静态访问它:

IHttpRequest httpReq = HostContext.AppHost.TryGetCurrentRequest(); 

但是当HttpContext.Current不为空时,这仍然仅适用于HTTP请求的上下文,因此无法在后台线程中工作。

直接从ICacheClient

访问

如果您以某种方式在ss-id Cookie中保留了会话ID,则可以直接从已注册的ICacheClient解析用户会话:

var sessionKey = SessionFeature.GetSessionKey(sessionId);
var session = cache.Get<IAuthSession>(sessionKey)