1

我正在使用 ServiceStack 开发基于 JWT 的多租户系统。JWT 令牌包含分片信息,我使用http://docs.servicestack.net/jwt-authproviderJwtAuthProvider上的说明将 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是我的自定义会话类。该技术源于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 代码,发现ExecuteMessage(IMessage dto, IRequest req)inServiceController似乎没有在RequestContext. 就我而言,在服务实例中获取会话为时已晚,因为服务实例依赖于一些数据库连接,其分片信息保存在会话中。

4

1 回答 1

1

无法从 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);
}
于 2018-06-16T15:25:26.460 回答