MassTransit - Обновление сообщений для клиента - PullRequest
4 голосов
/ 13 октября 2011

У меня нет особого опыта использования MSMQ, и кто-то порекомендовал мне взглянуть на MassTransit, чтобы помочь реализовать решение, но мне трудно понять, является ли использование MassTransit + MSMQ подходящим инструментом для работы.

У нас есть приложение WPF (3.5), которое используется несколькими пользователями.Постоянство осуществляется из приложения (через NHibernate) в базу данных.До сих пор пользователи периодически обновляли свои представления, чтобы быть в курсе последних обновлений.Однако теперь мы хотим отправлять уведомления каждому экземпляру приложения, когда сущность сохраняется с помощью обмена сообщениями pub / sub.Все клиентские приложения выполняются в одном домене и должны выполнять большинство требуемых зависимостей (например, установка MSMQ на клиентских компьютерах).

Подводя итог: Client1 публикует сообщение об обновлении ---> ?????----> Все остальные активные клиенты получают его.

Поскольку я новичок в MSMQ, я даже не уверен, как должна выглядеть архитектура.

  • Имеет ли каждый клиентмашине нужно иметь локальную очередь MSMQ для получения сообщений?
  • Нужно ли нам просто создавать очередь на сервере, и все клиенты прослушивают там сообщения?Если да, то будет ли достаточно одной или нескольких очередей или нам нужно создать службу для правильного распределения сообщений?
  • Является ли это даже подходящим инструментом для работы?

Я создал небольшую POC, надеясь, что это сработает, но в итоге я получил то, что, на мой взгляд, называется «Конкурирующий потребитель».Я хотел бы, чтобы один экземпляр приложения отправлял сообщение, а все экземпляры приложения получали его.

Будем весьма благодарны за любые предложения, указания или советы!

Вот код модели представления POC (примечание - на мой взгляд, localhost будетзаменить на сервер, на который каждый экземпляр приложения будет отправлять сообщения):

Обновление: добавлен сетевой ключ (котята)

Обновление: я загрузилпример кода https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0ByDMJXKmYB7zMjBmYzYwNDEtYzMwOC00Y2RhLTk1MDYtZjc0NTI2M2E3Y2Qy&hl=en_US

public class MainViewModel : IDisposable, INotifyPropertyChanged 
{
    private Guid id;

    public MainViewModel()
    {
        id = Guid.NewGuid();
        Publish = new RelayCommand(x => OnExecutePublishCommand(), x => !string.IsNullOrEmpty(Message));
        Messages = new ObservableCollection<MessagePayload>();

        Bus.Initialize(sbc =>
        {
            sbc.UseMsmq();
            sbc.SetNetwork("Kittens");
            sbc.VerifyMsmqConfiguration();
            sbc.UseMulticastSubscriptionClient();
            sbc.ReceiveFrom(string.Format("msmq://localhost/{0}", ConfigurationManager.AppSettings["queue"]));
            sbc.Subscribe(subs => subs.Handler<MessagePayload>(OnReceiveMessage));
        });
    }

    public ICommand Publish { get; private set; }

    private string message;
    public string Message
    {
        get { return message; }
        set
        {
            message = value;
            SendPropertyChanged("Message");
        }
    }

    public ObservableCollection<MessagePayload> Messages { get; private set; }

    private void OnReceiveMessage(MessagePayload msg)
    {
        Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, 
            new Action(() => Messages.Add(msg)));
    }

    private void OnExecutePublishCommand()
    {
        Bus.Instance.Publish(new MessagePayload{ Sender= id, Message = Message});
        Message = null;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void SendPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public void Dispose()
    {
        Bus.Instance.Dispose();
    }
}

Обновление : на случай, если кому-то будет интересно, мы разбили нашу «шину событий» на две части.Для сервера мы используем MassTransit.Однако, поскольку для Mass Transit требуется «полный профиль» (.NET 4.0), и мы хотели придерживаться «профиля клиента» для наших экземпляров WPF, мы используем SignalR для шины событий на стороне клиента.«Наблюдатель» на шине событий сервера пересылает сообщения на шину событий клиента.

1 Ответ

5 голосов
/ 13 октября 2011

Все машины в одной сети могут подписаться на данные сообщения.Всем им нужна локальная очередь для чтения.Не считывайте удаленные очереди, если нет абсолютно другого пути.

То, что вы описали, в целом кажется правильным.Есть сообщение, которое публикуется всем подписчикам, они получат его и обновят свое состояние.Я давно не работал с WPF, но в целом то, как вы справляетесь, кажется приемлемым.Обратите внимание, что для ускорения конфигурации MT может потребоваться некоторое время, поэтому вы можете сделать это в фоновом потоке, чтобы не блокировать пользовательский интерфейс.

Кроме того, для использования многоадресной подписки необходимо установить сетевой ключ.Он автоматически устанавливается на имя машины, если не указано иное.Вы хотите убедиться, что они могут успешно общаться друг с другом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...