我没有太多使用MSMQ的经验,有人建议我查看MassTransit以帮助实施解决方案,但我很难弄清楚使用MassTransit + MSMQ是否适合这项工作。< / p>
我们有一个由多个用户使用的WPF应用程序(3.5)。持久性是从应用程序(通过NHibernate)到数据库完成的。到目前为止,用户会定期刷新视图,以确保他们拥有最新的更新。但是,我们现在希望在使用发布/订阅消息传递持久化实体时向每个应用程序实例发送通知。客户端应用程序都在同一个域中运行,并且应该能够满足大多数所需的依赖项(例如,在客户端计算机上安装MSMQ)。
总结:Client1发布更新消息---&gt; ????? ----&GT;所有其他活跃客户都会收到它。
由于我是MSMQ的新手,我甚至不确定架构应该是什么样的。
我创建了一个小POC希望它可以工作,但我最终得到了我认为被称为“竞争消费者”的东西。我想要发生的是一个应用程序实例发送消息,所有应用程序实例都接收它。
我们非常感谢任何建议,方向或建议!
这是POC视图模型代码(注意 - 在我看来,localhost将替换为每个应用实例将发送消息的服务器):
更新:添加了网络密钥(小猫)
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();
}
}
更新:万一有人对此感兴趣,我们最终将“Event Bus”拆分为两个。对于服务器,我们使用的是MassTransit。但是,由于Mass Transit需要“完整配置文件”(.NET 4.0),并且我们希望坚持使用“客户端配置文件”作为我们的WPF实例,我们使用SignalR作为客户端事件总线。服务器事件总线上的“观察者”将消息转发到客户端事件总线。
答案 0 :(得分:5)
同一网络上的所有计算机都可以订阅给定的消息。他们都需要一个本地队列来读取。除非绝对没有办法,否则不要读取远程队列。
你所描述的似乎是正确的。有一条消息发布给所有订阅者,他们会收到并更新他们的状态。我有一段时间没有使用WPF,但一般来说你如何处理它似乎是可以接受的。请注意,启动MT配置可能需要一些时间,因此您可能希望在后台线程上执行此操作,这样您就不会阻止UI。
此外,使用多播订阅,您需要设置网络密钥。如果没有提供,它会自动设置为机器名称。你需要确保他们能够成功地相互交谈。