调查通知WPF客户端的服务器解决方案

16
我有一个项目需要在服务器上发生某些事件时通知WPF桌面客户端。此外,通知WPF客户端的消息不会广播(发送到每个客户端),而是应该发送给特定的客户端。
我想避免使用旧式的服务器轮询。这需要尽可能接近实时。
我以前从未有过这个要求,正在研究解决方案。我的第一个想法是使用SignalR.NET客户端。我还没有使用过SignalR,但它似乎可以成为一种解决方案。我知道这是长轮询、服务器推送事件和WebSockets的抽象,具体取决于可用性。
我简要了解了WCF回调和服务总线,但还不了解它们是否适用于此处的技术。我需要一些来自那些已经解决过这个问题的人的反馈和建议。你会如何处理?

客户端和服务器之间的连接是在受控网络内,还是通过“云”进行的? - Michael Brown
6个回答

7
这可以通过WCF和双工协定轻松完成。您可以定义客户端可以在服务器上执行的操作(就像任何Web服务一样),此外,您还可以定义服务器可以在客户端上执行的操作(即反向Web服务)。从代码角度来看,它们都只是简单的方法调用。客户端具有调用服务器上操作的方法,并且还必须提供实现回调协定的对象,这是服务器可以调用的接口,客户端必须提供实现。所有数据和消息的序列化/反序列化以及所有低级网络操作都由WCF处理,因此您不必担心它。
WCF使用两个绑定(或“协议”)支持双工协定:
  1. WSDualHttpBinding - 这需要两个基于SOAP的HTTP监听器,一个在服务器上,一个在客户端上。当客户端想要联系服务器时,它会向服务器执行HTTP请求。当服务器想要联系客户端时,它会向客户端执行HTTP请求。这种方法的优点是任何网络连接都是短暂的,并且不会保持打开(与大多数HTTP连接不同),因此可以支持大量并发客户端。主要缺点是它可能无法与大多数互联网上的客户端计算机配合使用,因为它们通常位于NAT后面(对于Internet上的服务器到服务器通信或任何局域网或LAN内部的通信而言,这不是问题)。有关更多详细信息,请参见我的其他答案

  2. NetTcpBinding - 这基本上是从客户端到服务器打开一个套接字,并将其保持打开状态,直到会话结束。即使在NAT上也允许双向通信,但由于必须保持连接打开,因此对服务器的负担略微增加,因此将能够支持较少的并发用户(但在大多数情况下仍然足够)。这是我首选在WCF上执行双工合同的方式,因为更容易使用且更可靠。

WCF的优势在于您可以在不更改代码的情况下切换两个绑定。所需的只是更改配置(.config文件)。
无论您选择哪种方式,都可以在两个方向上执行近乎即时的通信(当然,网络延迟要允许)。我认为当您拥有如此丰富、强大且易于使用的框架WCF时,就没有必要使用SignalR了。如果您受到浏览器运行的限制,则SignalR是有意义的。由于您正在运行.NET,使用SignalR只会引入不必要的摩擦。

1
我会进一步研究 WCF 的这个领域,但我考虑 SignalR 的原因是因为我的经验是 WCF 会引入不必要的阻力。 - Ronnie Overby

4
SignalR等技术的目的是满足服务器和Web客户端之间实时通信的需求。它们利用WebSockets,并针对旧版Web浏览器回退到较旧/更简单的通信机制。
如果您的环境将成为局域网,而您的客户端是.NET应用程序,则可以使用TCPServer和多个TCPClients。当您的Web服务器有更新/消息要发送时,请告诉您的TCPServer(可能是通过将消息放在其正在侦听的消息总线上),这可以通知已连接的客户端。实时Web技术是实现此目的的好方法,但这实际上取决于您当前的要求以及未来的计划:
  • 你想尝试SignalR吗 - 如果是,它会工作并且你可能会有很多乐趣。这也可能对未来的项目有所帮助,并成为你的一项好技能。如果不,TCPClient和TCPServer方法可能更简单,速度更快。
  • 你需要其他类型的Web客户端在未来能够接收通知吗? - 是的,SignalR或另一种更成熟的self hosted realtime web technology可能是更好的解决方案。否则 - 使用TCPServer/Client。
  • 你计划在局域网之外分发数据吗? 是 - 自托管选项或甚至带有.NET库的hosted solution可能是正确的选择,因为它们可以减少维护开销(免责声明:我为Pusher工作,他们提供此类服务)。否则 - 自托管或使用TCPServer/Client。
  • 速度有多重要? 如果速度真的很重要,那么没有任何额外开销的TCP连接将是最快的选项。第二好的选择是WebSockets,然后是HTTP流,最后是HTTP长轮询。
注意:虽然我说TCPServer / Client可能是最简单的方法,但我想强调它也可能不是。WebSockets是一种非常令人兴奋的技术,在许多方面比TCPClient技术更易于访问,因此可能成为任何服务器和客户端之间双向通信的主导技术。
我无法评论Duplex Contracts,但我的理解是它们建立的连接没有持久性,因此它们实际上是一种轮询解决方案 - 我可能错了。

双工合同不使用轮询,至少在框架提供的任何绑定中都不使用(也就是说,您可以编写自己的自定义绑定来执行各种疯狂的操作)。 - Allon Guralnek
他们用什么?HTTP流吗? - leggetter
啊,TCP - 用于TCP绑定 - 显然。对于HTTP,客户端实际上需要充当服务器,也就是拥有一个IP地址,以便从服务器向其发出HTTP请求。 - leggetter

3

你应该了解一下Frozen Mountain的WebSync。我过去使用它并取得了很好的效果。它能够满足你所有的需求。他们甚至提供托管服务“WebSync on Demand”。 他们也提供免费产品(但最多只支持10个并发用户)。 这是一个商业产品。如果你不想自己做所有的工作,WebSync为你提供了现成的API,你可以直接开始使用并快速上手。 我听说/读过SignalR,但还没有使用过,而SignalR似乎还处于alpha/beta阶段,而WebSync则非常成熟。


3
我还在评估一种轻量级且易于使用的方式,使用发布/订阅服务向WPF客户端通信事件。我不需要保证消息传递,因此像MassTransit或NServiceBus这样的解决方案似乎过于繁重,因为它们需要可用的队列(MSMQ或其他)。我还要求该解决方案作为.NET 4.0 客户端配置文件可用。
建立在WCF上的另一个解决方案是nvents。我不确定该项目是否仍然活跃。它易于使用,底层实现(WCF)也很好地抽象出来了。不需要复杂的配置。
我在Per Brage的博客上发现的另一个解决方案是使用SignalR和Reactive Extensions的事件代理。我没有尝试过他的实现,也不确定它是否需要完整的配置文件,但是很值得一读!

0

这个问题很有趣。

我们目前正在开发一个与多个Web服务交互的应用程序。其中一个要求是每个客户端都必须知道其他客户端进行的操作。

为了实现这一点,我们考虑创建一个仅用于构建要通知的客户端列表并处理通知逻辑的Web服务,客户端在启动时注册该服务。正如您提到的那样,通知本身将使用回调来完成。

之所以使用完全独立的Web服务,是因为我们所有现有的服务都需要在每次调用时建立和断开连接。通过通知Web服务,连接必须保持,只要客户端在运行中。

很抱歉我不能提供更多帮助,因为我们正在开发这样的系统。我也对此主题的反馈感兴趣。


0

您可以创建一个 WCF 服务,让 WPF 客户端在启动时注册自己。然后每个 WPF 客户端都可以与 MSMQ 或 RabbitMQ 服务器通信,在那里它们将轮询基于客户端名称/唯一 ID 创建的自己的队列。在服务器端,您可以拥有一个服务,根据为每个客户端设置的条件,在数据可用时将数据推送到队列中。


你可以在每台运行 WPF 应用程序的机器上都设置一个队列,并从队列中读取数据。只要使用 WPF,你就需要轮询某些内容以获取数据,除非你使用不如使用队列可靠的 wcf 回调函数来获取数据。 - rpgmaker
详细阐述为什么它不够可靠。 - Ronnie Overby
1
这不够可靠,因为您无法完全控制连接到您服务的客户端。您将不得不编写大量代码来管理检测客户端的断开和连接,例如检查客户端连接是否故障。在客户端失去连接的情况下,他们将丢失发送时断开连接的数据。如果您不介意丢失数据,那么这只是好的,但如果您想确保始终通知所有客户端,则需要一种持久化数据的方法。 - rpgmaker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接