4

私はMSMQの使用経験があまりなく、ソリューションの実装を支援するためにMassTransitを調べることを勧められましたが、MassTransit+MSMQを使用することがその仕事に適したツールであるかどうかを判断するのに苦労しています。

複数のユーザーが使用するWPFアプリケーション(3.5)があります。永続性は、アプリケーションから(NHibernateを介して)データベースに実行されます。これまで、ユーザーは最新の更新を確実に行うために、ビューを定期的に更新していました。ただし、エンティティがpub / subメッセージングを使用して永続化されたときに、各アプリケーションインスタンスに通知を送信する必要があります。クライアントアプリケーションはすべて同じドメイン内で実行され、必要なほとんどの依存関係を満たすことができる必要があります(たとえば、クライアントマシンへのMSMQのインストール)。

要約すると、Client1は更新メッセージを公開します---> ????? ---->他のすべてのアクティブなクライアントがそれを受け取ります。

私はMSMQを初めて使用するため、アーキテクチャがどのようになるべきかさえわかりません。

  • メッセージを受信するには、各クライアントマシンにローカルMSMQキューが必要ですか?
  • サーバー上にキューを作成するだけで、すべてのクライアントがそこでメッセージをリッスンする必要がありますか?もしそうなら、キューだけで十分ですか、それともメッセージを正しく配信するためにサービスを作成する必要がありますか?
  • これはその仕事に適したツールでさえありますか?

私はそれがうまくいくことを期待して少しPOCを作成しましたが、私は「競合する消費者」と呼ばれるものになりました。私がしたいのは、1つのアプリケーションインスタンスがメッセージを送信し、すべてのアプリケーションインスタンスがそれを受信することです。

任意の提案、方向性またはアドバイスをいただければ幸いです!

これがPOCビューモデルコードです(注-私の考えでは、ローカルホストは各アプリインスタンスがメッセージを送信するサーバーに置き換えられます):

更新:ネットワークキーを追加(子猫)

更新:サンプルコード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();
    }
}

更新:誰かが興味を持った場合に備えて、私たちは「イベントバス」を2つに分割することになりました。サーバーには、MassTransitを使用しています。ただし、大量輸送には「フルプロファイル」(.NET 4.0)が必要であり、WPFインスタンスには「クライアントプロファイル」を使用したかったため、クライアント側のイベントバスにはSignalRを使用しています。サーバーイベントバスの「オブザーバー」は、メッセージをクライアントイベントバスに転送します。

4

1 に答える 1

5

同じネットワーク上のすべてのマシンは、指定されたメッセージをサブスクライブできます。それらはすべて、読み取るためにローカルキューが必要です。他に方法が絶対にない場合を除いて、リモートキューを読み取らないでください。

あなたが説明したことは一般的に正しいようです。すべてのサブスクライバーに公開されるメッセージがあり、サブスクライバーはそれを受信して​​状態を更新します。私はしばらくの間WPFを使用していませんが、一般的に、WPFの処理方法は許容できるようです。MT構成の起動には少し時間がかかる場合があるため、UIをブロックしないように、バックグラウンドスレッドで起動することをお勧めします。

さらに、マルチキャストサブスクリプションを使用して、ネットワークキーを設定する必要があります。指定しない場合は、マシン名に自動的に設定されます。あなたは彼らがお互いにうまく話すことができることを確認したいと思うでしょう。

于 2011-10-13T17:46:21.063 に答える