Я новичок в архитектуре обмена сообщениями, поэтому, возможно, я ошибаюсь. Но я хотел ввести NServiceBus медленно в своей команде, разрешив крошечную проблему.Может ли такое же приложение быть как издателем/подписчиком с NServiceBus?
В пунктах повестки дня есть положения. Два пользователя могли бы посмотреть одно и то же назначение в той же повестке дня, в том же приложении. Они запускают это приложение через удаленный сеанс на центральном сервере. Поэтому, если пользователь 1 обновляет состояние назначения, я бы хотел, чтобы пользователь 2 увидел новое состояние «в реальном времени».
Чтобы имитировать это или сделать доказательство концепции, если хотите, я создал новое консольное приложение. Через NuGet я получил как NServiceBus, так и NServiceBus.Host, потому что, как я понял из документации, мне нужны оба. И я знаю, что в производственном коде не рекомендуется размещать все в одной сборке, но издатель и подписчик, скорее всего, попадут в одну и ту же сборку, хотя ...
В классе Программный метод Main Я написал следующий код :
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 (время ожидания для запрошенной операции истекло). Поэтому я должен делать что-то неправильно и заставляю меня предположить, что я не понимаю чего-то на более высоком уровне. Может ли кто-нибудь указать мне в правильном направлении, пожалуйста?
Update Everthing находится в пространстве имен AgendaUpdates, для класса событий, который находится в пространстве имен AgendaUpdates.Events кроме.
Update 2 шаги:
- Скопировано решение AgendaUpdates (в папку AgendaUpdates2)
- В копии я изменил MessageEndpointMappings в App.Config атрибут конечной точки "AgendaUpdates2" я получил Исключение MSMQ: «очередь не существует или у вас нет достаточных разрешений для выполнения операции»
- В копии я добавил эту строку кода в E ndPointConfig: configuration.EndpointName ("AgendaUpdates2"); я получил MSMQ исключения: «очередь не существует или у вас нет достаточных полномочий для выполнения операции»
- В копии я добавил эту строку коды в Main methodin класса программы: configuration.EndpointName ("AgendaUpdates2"); После повторного нажатия на кнопку снова появилось исключительное исключение.
-> Я проверил его, запустив 2 визуальных студии с оригинальным и скопированным решением. А затем запустите оба консольных приложения в среде IDE.
В вопросе вы опустили пространство имен, которое используется для указания имени конечной точки. Как говорит Фил, убедитесь, что у обеих есть своя уникальная очередь и укажите имя в коде, согласно документации, которую он предоставляет. Нет ничего плохого в том, что у издателя и подписчика есть тот же процесс. И все должно работать нормально на одной машине, необходимость развертывания на отдельной машине - это решение, принятое операциями и не имеющее никакого отношения к вашему коду. –
@Phil Sandler/@ Dennis van der Stelt Спасибо, что ответили. Я пытался реализовать ваши предложения, но я просто не могу заставить его работать. Я добавил stepts, сделанные в обновлении 2. Что я сделал неправильно? –
Обновлен мой ответ. –