ServiceStack MQ:如何在 RequestContext 中填充数据
ServiceStack MQ: how to populate data in RequestContext
我正在使用 ServiceStack 开发基于 JWT 的多租户系统。 JWT 令牌包含分片信息,我使用 JwtAuthProvider
按照 http://docs.servicestack.net/jwt-authprovider.
中的说明将 JWT 令牌转换为会话对象
现在想用ServiceStack MQ做异步处理。 MQ 请求需要知道分片信息,所以我在执行之前填充请求上下文,如下所示
mqServer.RegisterHandler<EmployeeAssignedToProject>(m =>
{
var req = new BasicRequest { Verb = HttpMethods.Post };
var sessionKey = SessionFeature.GetSessionKey(m.GetBody().SessionId);
var session = HostContext.TryResolve<ICacheClient>().Get<Context>(sessionKey);
req.Items[Keywords.Session] = session;
var response = ExecuteMessage(m, req);
return response;
});
这里,Context
是我的自定义会话class。此技术源于 http://docs.servicestack.net/messaging#authenticated-requests-via-mq 处的说明。由于我在 req
的上下文中执行消息,我认为我应该能够解析 Context
如下
container.AddScoped<Context>(c =>
{
var webRequest = HostContext.TryGetCurrentRequest();
if (webRequest != null)
{
return webRequest.SessionAs<Context>();
} else
{
return HostContext.RequestContext.Items[Keywords.Session] as Context;
}
});
但是,HostContext.RequestContext.Items
始终为空。所以问题是,如何从消息处理程序注册代码中填充 HostContext.RequestContext.Items
?
我尝试深入研究 ServiceStack 代码,发现 ServiceController
中的 ExecuteMessage(IMessage dto, IRequest req)
似乎没有填充 RequestContext
中的数据。就我而言,在服务实例中获取会话有点太晚了,因为服务实例依赖于一些分片信息保存在会话中的数据库连接。
无法从 IOC 解析相同的请求上下文实例。 Request Context 实例是在 MQ 的 RegisterHandler<T>()
中创建的,您可以在 IRequest.Items
属性 中添加自定义数据,例如:
mqServer.RegisterHandler<EmployeeAssignedToProject>(m =>
{
var req = new BasicRequest { Verb = HttpMethods.Post };
req.Items[MyKey] = MyValue; //Inject custom per-request data
//...
var response = ExecuteMessage(m, req);
return response;
});
此 IRequest
实例在整个请求管道和您的服务中的 base.Request
中可用。它在您的 IOC 注册中不可用,因此您需要在调用依赖项时将其作为参数传递,例如:
public class MyServices : Service
{
public IDependency MyDep { get; set; }
public object Any(MyRequest request) => MyDep.Method(base.Request, request.Id);
}
我正在使用 ServiceStack 开发基于 JWT 的多租户系统。 JWT 令牌包含分片信息,我使用 JwtAuthProvider
按照 http://docs.servicestack.net/jwt-authprovider.
现在想用ServiceStack MQ做异步处理。 MQ 请求需要知道分片信息,所以我在执行之前填充请求上下文,如下所示
mqServer.RegisterHandler<EmployeeAssignedToProject>(m =>
{
var req = new BasicRequest { Verb = HttpMethods.Post };
var sessionKey = SessionFeature.GetSessionKey(m.GetBody().SessionId);
var session = HostContext.TryResolve<ICacheClient>().Get<Context>(sessionKey);
req.Items[Keywords.Session] = session;
var response = ExecuteMessage(m, req);
return response;
});
这里,Context
是我的自定义会话class。此技术源于 http://docs.servicestack.net/messaging#authenticated-requests-via-mq 处的说明。由于我在 req
的上下文中执行消息,我认为我应该能够解析 Context
如下
container.AddScoped<Context>(c =>
{
var webRequest = HostContext.TryGetCurrentRequest();
if (webRequest != null)
{
return webRequest.SessionAs<Context>();
} else
{
return HostContext.RequestContext.Items[Keywords.Session] as Context;
}
});
但是,HostContext.RequestContext.Items
始终为空。所以问题是,如何从消息处理程序注册代码中填充 HostContext.RequestContext.Items
?
我尝试深入研究 ServiceStack 代码,发现 ServiceController
中的 ExecuteMessage(IMessage dto, IRequest req)
似乎没有填充 RequestContext
中的数据。就我而言,在服务实例中获取会话有点太晚了,因为服务实例依赖于一些分片信息保存在会话中的数据库连接。
无法从 IOC 解析相同的请求上下文实例。 Request Context 实例是在 MQ 的 RegisterHandler<T>()
中创建的,您可以在 IRequest.Items
属性 中添加自定义数据,例如:
mqServer.RegisterHandler<EmployeeAssignedToProject>(m =>
{
var req = new BasicRequest { Verb = HttpMethods.Post };
req.Items[MyKey] = MyValue; //Inject custom per-request data
//...
var response = ExecuteMessage(m, req);
return response;
});
此 IRequest
实例在整个请求管道和您的服务中的 base.Request
中可用。它在您的 IOC 注册中不可用,因此您需要在调用依赖项时将其作为参数传递,例如:
public class MyServices : Service
{
public IDependency MyDep { get; set; }
public object Any(MyRequest request) => MyDep.Method(base.Request, request.Id);
}