16

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

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

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

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

4

6 回答 6

7

使用 WCF 和双工合同可以很容易地做到这一点。您可以定义客户端可以在服务器上执行的操作(如任何 Web 服务),此外您还可以定义服务器可以在客户端上执行的操作(即反向 Web 服务)。代码方面,它们都只是简单的方法调用。客户端具有调用服务器上操作的方法,它还必须提供一个实现回调合约的对象,这是一个服务器可以调用的接口,客户端必须提供一个实现。所有数据和消息的序列化/反序列化以及所有低级网络操作都由 WCF 处理,因此您不必担心。

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

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

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

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

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

于 2011-12-15T19:19:08.223 回答
4

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

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

  • 你想试试 SignalR - 如果是,那么它会起作用,你可能会玩得很开心。它也可能对未来的项目有用,并成为你弓上的一根好绳子。如果不是,TCPClient 和 TCPServer 方法可能会超级简单且执行速度更快。
  • 您是否需要其他类型的 Web 客户端将来能够接收通知?- 是的,SignalR 或其他更成熟的自托管实时 Web 技术可能是更好的解决方案。否 - TCPServer/Client
  • 您是否计划将数据分发到 LAN 之外?是的 - 自托管选项或事件与 .NET 库的托管解决方案可能是要走的路,因为它们消除了维护开销(免责声明:我为提供此类服务的Pusher工作) 。否 - 自托管或 TCPServer/Client。
  • 速度有多重要?如果它真的很重要,那么绝对没有开销的 TCP 连接将是最快的选择。第二个最好的选择是 WebSockets,然后是 HTTP 流,然后是 HTTP 长轮询。

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

我不能评论双工合同,但我的理解是他们建立的连接没有持久化,所以它们实际上是一个轮询解决方案——我可能是错的。

于 2011-12-16T15:36:43.797 回答
3

我还在评估一种使用发布/订阅服务与 WPF 客户端进行事件通信的轻量级且简单的方法。我不需要保证消息传递,因此 MassTransit 或 NServiceBus 之类的解决方案似乎过于繁重,因为它们需要可用的队列(MSMQ 或其他)。我还要求该解决方案可以作为 .NET 4.0 Client Profile使用。

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

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

于 2012-05-23T04:24:33.540 回答
3

您应该从 Frozen Mountain 中查看WebSync 。我过去用过它,效果很好。它可以满足您的所有要求。他们甚至提供托管服务“WebSync on Demand”。他们还提供免费产品(但最多 10 个并发用户)。它是一种商业产品。如果您不想做所有的管道,WebSync 为您提供准备使用的 api,您可以开始使用并快速开始使用。我听说过/读过 SignalR,还没有使用过,但 SignalR 似乎处于 alpha/beta 阶段,而 WebSync 非常成熟。

于 2011-12-15T19:21:42.887 回答
0

这个问题很有趣。

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

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

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

很抱歉,我无法提供更多帮助,因为我们正在自己开发这样的系统。我也有兴趣获得有关此主题的反馈。

于 2011-12-15T18:02:42.357 回答
0

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

于 2011-12-15T19:37:27.847 回答