Demis!首先,如果我把你的时间花在那个目标上,我想道歉。我们有一个基于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
}
});
因此,我正确接收消息,但无法获取当前会话上下文。是否可以在插件模块中获取会话?你能帮忙吗?
提前感谢!
相关联,因为会话由会话 Cookie 标识,因此它们只能在 HTTP 请求的上下文中解析,因此您需要访问IRequest
才能使用 GetSession()
扩展方法解析会话,例如:
var session = req.GetSession();
在 ServiceStack 内部,IRequest
在请求过滤器或 base.Request
属性中可用 服务、Razor 视图等。还有许多方法可以在ServiceStack之外访问IRequest,例如:
IHttpRequest httpReq = aspCtx.ToRequest(); //HttpContext
IHttpRequest httpReq = aspReq.ToRequest(); //MVC HttpRequestBase
IHttpRequest httpReq = listenerCtx.ToRequest(); //HttpListenerContext
在 ASP.NET 主机中,您可以通过单一实例静态访问它:
IHttpRequest httpReq = HostContext.AppHost.TryGetCurrentRequest();
但这仍然仅适用于 HTTP 请求的上下文,当 HttpContext.Current
不为 null 时,因此在后台线程中不起作用。
直接从ICache客户端访问
如果您以某种方式掌握了 Cookie ss-id
会话 ID,则可以使用以下方法直接从注册ICacheClient
解析用户会话:
var sessionKey = SessionFeature.GetSessionKey(sessionId);
var session = cache.Get<IAuthSession>(sessionKey)