【发布时间】:2017-08-29 17:44:42
【问题描述】:
我正在尝试向 Masstransit 消息添加一个标头,该消息包含来自 WCF Web 应用程序上当前登录用户的信息。
所以在我的网络应用程序中,当应用程序启动时,我有以下内容:
IBusControl bus = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
cfg.Host(new Uri("rabbitmq://localhost/test"), r =>
{
//...
});
cfg.ConfigureSend(
s => s.UseSendExecute(
c => c.Headers.Set(Constants.UserInfo,
OperationContext.Current.Channel.Extensions.Find<PropertyUserInfo>().Info)));
});
我使用 IoC 容器在应用程序中仅创建一次
IBusControl(单例范围),然后将 IBusControl 注入 Web 服务。请注意,当我创建服务总线时,
OperationContext.Current不存在,我希望在请求上下文中调用 lambdac= > c.Headers.Set(...)
现在,当用户发出请求时,我使用的是请求-响应模式(尽管我认为这并不重要)
var requestClient = _bus.CreateRequestClient<AddTicketRequest, AddTicketResponse>(uri, timeout);
var response = requestClient.Request(requestMessage);
问题是,当执行此代码时,Masstransit 尝试将标头添加到消息中,OperationContext.Current 是 null,因为显然它运行在与用户调用不同的线程上。
奇怪的是,最终 Masstransit 开始从正确的线程调用 UseSendExecute,一切都开始工作了。而且我必须重新启动 IIS 才能再次复制错误(!?)。
有人遇到过这个问题吗?谢谢。
我知道我可以在发布消息时添加标头,但我希望来自 Web 应用程序的所有消息都具有此标头,并希望将其设置为全局。 p>
【问题讨论】:
-
为什么在发送请求时不设置标头,您在上下文中的位置,以便可以使用局部变量进行闭包?
-
@AlexeyZimarev,谢谢,我想我可以在调用
CreateRequestClient时设置标题,但我必须为每一次调用都这样做。我希望在端点过滤器上处理用户信息(例如访问权限) -
@AlexeyZimarev 你会这样做吗?
-
此外,我还有
_bus.Publish、路由单等其他用例。我必须为每个用例都这样做 -
我认为这个问题更多的是意识形态,它不是关于线程,而是更多关于当你发送消息时处于网络请求的上下文中。如果您使用 IoC 容器,您可能可以从那里获取一些上下文信息,因为通常您已经为每个请求封装了上下文。
标签: c# wcf masstransit nettcpbinding operationcontext