研究从服务器通知WPF客户端的解决方案

时间:2011-12-15 14:34:16

标签: .net wpf client-server server-push signalr

我有一个项目需要在服务器上发生某些事情时通知WPF桌面客户端。此外,WPF客户端的通知不会被广播(发送给每个客户端),应该发送给特定的客户端。

我想远离旧式服务器轮询。这需要尽可能接近实时。

我之前从未有过这个要求,而且我正在研究解决方案。我的第一个想法是将SignalR.NET client一起使用。我还没有使用过SignalR,但似乎它可能是一个解决方案。我知道这是对长轮询,服务器发送事件和WebSockets的抽象,具体取决于可用的内容。

我已经简要介绍了使用回调和服务总线的WCF,但对它们一无所知或这些技术是否适用于此。我可以使用之前解决过这个问题的人的反馈和建议。你会怎么做?

6 个答案:

答案 0 :(得分:7)

使用WCF和duplex contracts可以非常轻松地完成此操作。您可以定义客户端可以在服务器上执行的操作(如任何Web服务),此外,您还可以定义服务器可以在客户端上执行的操作(即反向Web服务)。代码方面,它们只是简单的方法调用。客户端具有调用服务器上的操作的方法,并且还必须提供实现回调契约的对象,该回调契约是服务器可以调用的接口,客户端必须提供实现。所有数据和消息的序列化/反序列化以及所有低级网络操作都由WCF处理,因此您不必担心它。

WCF支持使用两个绑定(或“协议”)的双工合同:

  1. WSDualHttpBinding - 这需要两个基于SOAP的HTTP侦听器,一个在服务器上,另一个在客户端上。当客户端想要联系服务器时,它会向服务器执行HTTP请求。当服务器想要联系客户端时,它会向客户端执行HTTP请求。这种方法的优点是任何网络连接都是短暂的,并且不会保持打开(与大多数HTTP连接一样),因此它可以支持大量或并发客户端。主要的缺点是它可能无法通过互联网与大多数客户端计算机一起使用,因为它们通常位于NAT之后(通过Internet进行服务器到服务器通信或内部网或LAN内的任何类型的通信都没有问题) 。有关详细信息,请参阅我的other answer

  2. NetTcpBinding - 这基本上打开了从客户端到服务器的套接字,并在会话期间保持打开状态。这允许甚至通过NAT进行双向通信,但由于连接必须保持打开,这对服务器来说有点负担,因此能够支持较少的并发用户(但在大多数情况下可能仍然绰绰有余)。这是我在WCF上进行双工合同的首选方式,因为它更容易上班,更可靠。

  3. WCF的优点是您可以在不更改代码的情况下在两个绑定之间切换。所需的只是更改配置(.config文件)。

    无论您选择哪种方式,您都可以在两个方向上进行近乎即时的通信(当然,网络延迟允许)。当您拥有如此丰富,功能强大且易于使用的框架(如WCF)时,我不认为需要SignalR。如果你受到浏览器运行的限制,那么SignalR就有意义了。由于你在.NET中运行,它只会引入不必要的摩擦。

答案 1 :(得分:4)

SignalR等技术的目的是满足服务器和Web客户端之间实时通信的需求。他们利用WebSockets并回退旧版Web浏览器的旧版/黑客通信机制。

如果您的环境将成为LAN,而您的客户端将成为.NET应用程序,那么您可以使用TCPServer和多个TCPClient。当您的Web服务器有要发送的更新/消息时,请告诉您的TCPServer(可能通过在其正在侦听的消息总线上发送消息),这可以通知所连接的客户端。实时网络技术是一种很好的方法,但它实际上取决于您当前的要求以及您对未来的计划:

  • 你想尝试SignalR - 如果是,那么它会起作用,你可能会有很多乐趣。它对于未来的项目也可能有用,并且可以成为一个很好的字符串。如果不是,TCPClient和TCPServer方法可能非常简单且更快。
  • 您是否要求其他类型的网络客户端能够在将来接收通知? - 是的,SignalR或其他更成熟的self hosted realtime web technology可能是更好的解决方案。否 - TCPServer / Client
  • 您是否计划在局域网外部分发数据?是 - 自我托管的选项或事件hosted solution与.NET库可能是他们删除维护费用(免责声明:我为提供此类服务的Pusher工作)。否 - 自托管或TCPServer /客户。
  • 速度多少重要?如果真的很重要,那么绝对没有开销的TCP连接将是最快的选择。第二个最佳选项是WebSockets,然后是HTTP Streaming,然后是HTTP Long-Polling。

注意:虽然我说TCPServer / Client可能是最简单的方法,但我想强调它也可能不是。 WebSockets是一项非常令人兴奋的技术,在很多方面比TCPClient技术更易于访问,因此可能成为任何服务器和客户端之间双向通信的主导技术 *

我无法评论双面合同,但我的理解是他们建立的连接没有持久化,所以他们实际上是一个民意调查解决方案 - 我可能是错的。

答案 2 :(得分:3)

你应该从冰山看看WebSync。我过去使用过它,效果很好。它可以满足您的所有需求。他们甚至提供托管服务'WebSync on Demand'。 他们也提供免费产品(但最多10个并发用户)。 它是一种商业产品。如果你不想做所有的管道,WebSync可以让你准备好使用api,你可以开始使用并快速进行。 我听说过/读过有关SignalR的信息,尚未使用它,但SignalR似乎处于alpha / beta状态,而WebSync则非常成熟。

答案 3 :(得分:3)

我还在评估使用pub / sub服务将事件传递给WPF客户端的轻量级简单方法。我没有要求保证消息传递,因此像MassTransit或NServiceBus这样的解决方案似乎太重了,因为它们需要队列可用(MSMQ或其他)。我还要求该解决方案可用作.NET 4.0 客户端配置文件

基于WCF构建的一个似乎有效的解决方案是nvents。我不确定该项目是否仍然有效。它易于使用,底层实现(WCF)很好地抽象化。不需要讨厌的配置。

我在Per Brage的Blog上遇到的另一个解决方案是使用SignalR和Reactive Extensions。我没有尝试过他的实现,我不确定它是否需要完整的配置文件,但是读起来很好!

答案 4 :(得分:0)

这个问题很有意思。

我们目前正在开发一个与多个Web服务交互的应用程序。其中一个要求是每个客户必须了解其他客户所做的操作。

为了实现这一目标,我们正在考虑创建一个Web服务,其目的只是构建一个要通知的客户端列表,并处理通知后面的逻辑,时间和通知的内容。客户将在启动时注册该服务。如上所述,通知本身将使用回调来完成。

使用完全独立的Web服务背后的原因是因为我们现有的所有服务都需要在每次调用时建立和删除连接。使用通知Web Service,只要客户端运行,就必须保持连接。

对不起,我无法提供更多帮助,因为我们正在自己开发这样一个系统。我也有兴趣获得关于这个主题的反馈。

答案 5 :(得分:0)

您可以创建一个wcf服务,其中wpf客户端在启动时注册它们。然后每个wpf可以与msmq或rabbitmq服务器通信,在那里他们将轮询根据客户端名称/唯一ID创建的自己的队列。在服务器端,您可以使用一种服务,根据为每个客户端设置的条件,将数据推送到队列中。