我是消息体系结构的新手,所以我可能会以这种错误的方式去做。但是我想通过解决一个小问题,在我的团队中慢慢地介绍NServiceBus。同一个应用程序可以是NServiceBus的发布者/订阅者吗?
议程中的任命有州。两个用户可以在同一个应用程序中查看同一个议程中的同一个约会。他们通过中央服务器上的远程会话启动该应用程序。因此,如果用户1更新了约会的状态,我希望用户2看到新的状态'实时'。
为了模拟这种或进行概念证明,如果你愿意,我做了一个新的控制台应用程序。通过NuGet我得到NServiceBus和NServiceBus.Host,因为我从文档中理解我需要两个。我知道在生产代码,不建议把一切都在同一程序,但出版商和用户将最有可能在同一程序虽然结束了......
在类节目的方法主要我写了下面的代码:
BusConfiguration configuration = new BusConfiguration();
configuration.UsePersistence<InMemoryPersistence>();
configuration.UseSerialization<XmlSerializer>();
configuration.UseTransport<MsmqTransport>();
configuration.TimeToWaitBeforeTriggeringCriticalErrorOnTimeoutOutages(new TimeSpan(1, 0, 0));
ConventionsBuilder conventions = configuration.Conventions();
conventions.DefiningEventsAs(t => t.Namespace != null
&& t.Namespace.Contains("Events"));
using (IStartableBus bus = Bus.Create(configuration))
{
bus.Start();
Console.WriteLine("Press key");
Console.ReadKey();
bus.Publish<Events.AppointmentStateChanged>(a =>
{
a.AppointmentID = 1;
a.NewState = "New state";
});
Console.WriteLine("Event published.");
Console.ReadKey();
}
在类EndPointConfig方法自我加入:
configuration.UsePersistence<InMemoryPersistence>();
configuration.UseSerialization<XmlSerializer>();
configuration.UseTransport<MsmqTransport>();
ConventionsBuilder conventions = configuration.Conventions();
conventions.DefiningEventsAs(t => t.Namespace != null
&& t.Namespace.Contains("Events"));
AppointmentStateChanged处于活动的简单类文件夹,如下所示:
public class AppointmentStateChanged: IEvent {
public int AppointmentID { get; set; }
public string NewState { get; set; }
}
AppointmentStateChangedHandler是事件处理程序:
public class AppointmentStateChangedHandler : IHandleMessages<Events.AppointmentStateChanged> {
public void Handle(Events.AppointmentStateChanged message) {
Console.WriteLine("AppointmentID: {0}, changed to state: {1}",
message.AppointmentID,
message.NewState);
}
}
如果我启动一个控制台应用程序,一切工作正常。我看到处理程序处理事件。但是,如果我尝试启动第二个控制台应用程序,它会崩溃:System.Messaging.MessageQueueException(请求的操作超时已过期)。所以我必须做出错误的事情,让我第二次猜测我不了解更高层次的事情。任何人都可以向我指出正确的方向吗?
更新 寄托都在命名空间AgendaUpdates,除了事件类,这是在AgendaUpdates.Events命名空间。采取
更新2 步骤:
- 复制AgendaUpdates解决方案(以AgendaUpdates2文件夹)
- 在副本中我App.Config中改变MessageEndpointMappings的端点属性为 “AgendaUpdates2” 我MSMQ例外:“队列不存在,或者您没有足够的权限来执行的操作”
- 在我加入这行代码到E副本ndPointConfig:configuration.EndpointName( “AgendaUpdates2”); 我MSMQ例外:“队列不存在,或者您没有足够的权限来执行的操作”
- 在我加入这行代码到主架法程序类的副本: configuration.EndpointName ( “AgendaUpdates2”); 按键后再次出现原始异常。
- >我用原始和复制的解决方案开始2视觉工作室的测试。然后在IDE中启动两个控制台应用程序。
在这个问题中,您省略了用于指定端点名称的名称空间。正如菲尔所说,根据他提供的文件,确保两者都有自己的唯一队列并在代码中指定名称。 让发布商和订阅者在同一个过程中没有任何问题。所有的一切都应该运行在同一台机器上的罚款,来部署一个单独的机器上,需要的是通过行动作出的决定,并没有任何与您的代码。 –
@Phil Sandler/@ Dennis van der Stelt谢谢你的回答。我一直在努力执行你的建议,但我似乎无法得到它的工作。我已经添加了更新2中采取的步骤。我做错了什么? –
更新了我的答案。 –