Winforms 发布客户端事件的推荐消息总线体系结构

Winforms 发布客户端事件的推荐消息总线体系结构,winforms,msmq,messaging,nservicebus,esb,Winforms,Msmq,Messaging,Nservicebus,Esb,对于以下场景,建议的消息传递体系结构是什么: 运行WinForms客户端的多个工作站 客户端必须可靠地将事件通知两个(或多个)Windows服务 最初,我们希望避免在客户端工作站上配置MSMQ,因此我们创建了一个web服务。这证明很难配置,然后我了解到从web应用程序发布NServiceBus消息非常困难 最佳做法是: 让客户端调用一个web服务,该服务向发布消息的Windows服务发送(而不是发布)消息 是否将消息直接从客户端应用程序发送(而不是发布)到服务器上的远程队列,Windows

对于以下场景,建议的消息传递体系结构是什么:

  • 运行WinForms客户端的多个工作站
  • 客户端必须可靠地将事件通知两个(或多个)Windows服务
最初,我们希望避免在客户端工作站上配置MSMQ,因此我们创建了一个web服务。这证明很难配置,然后我了解到从web应用程序发布NServiceBus消息非常困难

最佳做法是:

  • 让客户端调用一个web服务,该服务向发布消息的Windows服务发送(而不是发布)消息
  • 是否将消息直接从客户端应用程序发送(而不是发布)到服务器上的远程队列,Windows服务将从该队列发布消息
  • 其他的
目前,我正在尝试使用NServiceBus实现这一点,但希望答案是总线不可知的

编辑:


如果客户端只是发送(而不是发布)到远程队列,是否需要在客户端工作站上配置(甚至安装)MSMQ?在这种情况下,如果无法访问远程队列,会发生什么情况?

我认为客户端应该按照选项二的建议直接向服务器发送消息。尽管您必须在客户端工作站上配置msmq。你为什么不想这样做

这具有端到端耐用性的优点

我注意到您谈到了发送vs发布,但是在您的场景中,我看不到任何值得使用NSB pub-sub的内容


仅供参考,发送到远程队列并从本地队列读取几乎总是最好的选择。

您可以将NServiceBus端点公开为WCF服务

从页面底部开始:

公共类MyService:NServiceBus.WcfService
{
...
}
看看这个。您应该能够让客户端应用程序连接到WCF服务以丢弃消息。您可以使用http、net.tcp或任何适合您的WCF传输配置WCF服务

该服务将不再是web应用程序,即使它使用HTTP传输(尽管您可能必须选择非标准端口)。它将是一个公开web服务接口的Windows服务。可以在这里发布消息。这使您不必在所有客户机上配置MSMQ,但仍然具有很大的NServiceBus易用性和灵活性


当然,如果需要考虑此服务的可伸缩性,您可能希望使用负载平衡的IIS托管web服务。在这种情况下,请创建一个普通的WCF web服务,将消息发送到作为Windows服务安装的NServiceBus.Host.exe端点,然后从该Windows服务发布事件。

+1谢谢。关于MSMQ,我们试图最小化配置和可能出错的事情。我们会重新考虑的。至于酒吧酒吧,我认为好处是脱钩。如果客户端直接发送到两个目标队列,并且我们想要添加第三个目标,那么我们不需要修改客户端吗?使用pub-sub,我们只需添加另一个订阅者。或者我遗漏了什么?使用pub-sub的问题是,在您的场景中,客户端实际上是发布者,服务器是订阅者。它会把所有东西都翻过来。然后,服务器必须向所有存在的客户端实例发送订阅消息,以便从它们接收消息。最好让订阅者向一个逻辑发布服务器发送订阅(如果设置中有冗余,则可能涉及多个队列地址)。我特别避免让客户端发布服务器。我的目的是要有一个出版商,这是一个服务。服务器订阅了这个。客户端只需将事件通知发布者;出版商出版了它们。从某种意义上说,是的,客户端是“逻辑”发布者(但不是NServiceBus使用该术语的扩展意义)。但这是业务需求。如果有更好的方法来实现它,那就是我要问的。好的,是的,我知道你现在在说什么。这似乎是一个很好的解决方案。我真的想接受这两个答案,因为你和@David都提供了谜题的一部分。谢谢你的回复!在幕后,WcfService调用bus.Send,而不是Publish。我是否将MyCommand消息发送到发布服务器服务(也承载WcfService)的InputQueue,然后设置发布它的消息处理程序?这似乎太复杂了。它是Bus.Send()将MyCommand发送到MyCommand应该去的任何地方。将MyCommand视为WCF客户机到WCF服务器的命令,或者视为web服务的WSDL。它所做的只是获取WCF请求并将其放到总线上。您可以指定MyCommand转到服务自己的InputQueue,并在同一个类中使用Handle(MyCommand)方法,然后在该类中发布不同的消息类型,即“现在我住在服务总线上的真实消息”消息。希望这能澄清?@truewill-是的,你误解了。NServiceBus服务/客户端都有一个输入队列。这可以接收任何类型的消息。对于发布者,它将在其输入队列上接收的消息类型之一是订阅消息。“一个队列应仅处理一种类型的消息”的来源是这样一个事实,即控制可伸缩性和处理SLA的单元是输入队列。一旦在同一队列中处理两种类型的消息,就不能将它们分开,也不能赋予一种消息类型更高的优先级。因此,为了实现最大的灵活性,是的,每个队列有一种消息类型,不包括订阅请求等管理消息。在您的情况下,如果需要负载平衡WCF服务,我将允许负载平衡器后面的多个WCF接收器对所有总线发送()转换后的消息(通过WcfService类)到执行发布的中心端点。如果sc
public class MyService : NServiceBus.WcfService<MyCommand, MyErrorCodes>
{
    ...
}