我正在尝试设置MassTransit请求/响应方案。问题是消息永远不会到达消费者手中。我在PublishRequest上收到“超时等待响应”错误。日志文件中没有显示其他错误。正在以msmq。
创建消息异常信息:
异常类型:TargetInvocationException 异常消息:调用目标抛出了异常。在System.RuntimeTypeHandle.CreateInstance(RuntimeType type,Boolean publicOnly,Boolean noCheck,Boolean& canBeCached, RuntimeMethodHandleInternal&安培; ctor,布尔& bNeedSecurityCheck)at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly,Boolean skipCheckThis,Boolean fillCache,StackCrawlMark& stackMark)at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis,Boolean fillCache,StackCrawlMark& stackMark)
在System.Activator.CreateInstance(Type type,Boolean nonPublic)at System.Activator.CreateInstance(Type type)at System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create(的RequestContext requestContext,Type controllerType)超时等待响应,RequestId: 08cfa243-4a88-ba3a-20cf-307f54910000 at MassTransit.RequestResponse.RequestImpl
1.Wait() in d:\BuildAgent-03\work\8d1373c869590c5b\src\MassTransit\RequestResponse\RequestImpl.cs:line 124 at MassTransit.RequestResponseExtensions.PublishRequest[TRequest](IServiceBus bus, TRequest message, Action
1 configureCallback)in d:\ BuildAgent-03 \工作\ 8d1373c869590c5b的\ src \ MassTransit \ RequestResponseExtensions.cs:行 31在Producer.Website.Controllers.AccountController..ctor()中 c:\ Users \ rick \ Documents \ Visual Studio 2012 \项目\ ConsumerTest1 \ Producer.Website \ \控制器AccountController.cs:行 56
制片人设置:
_bus = ServiceBusFactory.New(sbc =>
{
sbc.UseMsmq();
sbc.VerifyMsmqConfiguration();
sbc.UseMulticastSubscriptionClient();
sbc.SetNetwork("Test");
sbc.ReceiveFrom("msmq://localhost/consumer_test_1");
});
制作人发送消息:
var message = new AccountNewMessage()
{
CorrelationId = CombGuid.Generate(),
UserName = “blah blah”,
Password = “yada yada”
};
this._bus.PublishRequest(message, r =>
{
r.SetTimeout(30.Seconds());
r.Handle<AccountNewMessageResponse>(m =>
{
var response = m;
});
});
消费者设置:
this.bus = ServiceBusFactory.New(sbc =>
{
sbc.UseMsmq();
sbc.VerifyMsmqConfiguration();
sbc.UseMulticastSubscriptionClient();
sbc.SetNetwork("Test");
sbc.ReceiveFrom("msmq://localhost/consumer_test_2");
sbc.Subscribe(subs => subs.Instance(new AccountNewMessageConsumer()));
});
消费者:
public class AccountNewMessageConsumer : Consumes<AccountNewMessage>.Context
{
public void Consume(IConsumeContext<AccountNewMessage> context)
{
context.Respond(new AccountNewMessageResponse()
{
CorrelationId = context.Message.CorrelationId,
ErrorCode = "1",
UserId = new Random().Next(1, 10000).ToString()
});
}
}
消息:
[Serializable]
public class AccountNewMessage : CorrelatedBy<Guid>
{
public Guid CorrelationId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
}
[Serializable]
public class AccountNewMessageResponse : CorrelatedBy<Guid>
{
public Guid CorrelationId { get; set; }
public string UserId { get; set; }
public string ErrorCode { get; set; }
}
我做错了什么?谢谢。
答案 0 :(得分:0)
您必须告诉MassTransit如何存储它的订阅信息(对于MSMQ)。
有两种选择:MSMQ Multicast
,它将订阅信息保存在内存中,MSMQ Runtime Services
将订阅信息存储在数据库中,因此它会在会话之间保留。
您选择使用哪个将取决于您是否需要永久或临时订阅 - 来自the docs:
永久订阅代表您想要的订阅 即使你的过程被关闭,也要留下来(也许你正在做一个 升级,不想错过任何消息)。临时订阅是 如果你错过了一条消息,你将不在乎的情况下使用 关闭时。
没有理由在开发/ PoC期间无法使用多播,以后再切换到RuntimeServices。文档页面还显示了如何在配置中设置每个,当然使用RuntimeServices,您还必须设置数据库。
(请注意,多播可能需要一段时间才能自行设置,因此您可能需要在开始通过它传送消息之前暂停预热测试系统。)
编辑:我已经附加了几个验证订阅和消费者的例程:您可以在设置订阅时(即在sbc.Subscribe期间)调用第一个,在配置总线后调用第二个。也许他们会帮助找到问题?
private void ValidateSubscriptions(Configurator configurator)
{
var errors = configurator.Validate();
Console.WriteLine("Subscription Validation");
Console.WriteLine("-----------------------");
foreach (var err in errors.Where(e => string.IsNullOrEmpty(e.Value) == false))
{
Console.WriteLine("Type: {0} Message: {1} Key: {2} Value: {3}",
err.Disposition, err.Message, err.Key, err.Value);
}
}
private static void ValidateBus(Configurator bus)
{
var errors = bus.Validate();
Console.WriteLine("Consumer Validation");
Console.WriteLine("-------------------");
foreach (var err in errors.Where(e => string.IsNullOrEmpty(e.Value) == false))
{
Console.WriteLine("Type: {0} Message: {1} Key: {2} Value: {3}",
err.Disposition, err.Message, err.Key, err.Value);
}
}