服务器和客户端之间的WinForms通信

3
我有50多个类似于信息亭的电脑,我希望能够从单个电脑上按需获取状态更新,而不是定期获取。这些电脑与请求状态的电脑在局域网中。
我研究了WCF,但看起来我需要安装IIS,而我不想在50多个Windows XP盒子上安装IIS,所以除非有可能让WinForm托管Web服务,否则我认为这排除了使用Web服务的可能性。
我还研究了使用System.Net.Sockets,甚至做了一个几乎能工作的原型,但我觉得我没有足够的技能使它成为一个稳定可靠的系统。如果选择这条路,我需要学习更多关于套接字编程和线程的知识。
这些盒子正在运行.NET 3.5 SP1,因此我在.NET版本上有完全的灵活性,但我想坚持使用C#。
最佳实现方式是什么?我应该咬紧牙关学习套接字,还是.NET有更好的处理方法?
编辑:我本来想采用双向通信,直到我意识到我只需要单向通信。
编辑2:我避免传统的服务器/客户端,并选择了反向,因为我想避免消耗过多的带宽,并不确定我在谈论什么样的开销。我还希望能够更好地控制各个信息亭。看了一下,我认为我仍然可以通过IP连接使用WCF,并且(我不知道我可以通过IP连接)连接(我原本以为我需要添加50个Web服务或类似的东西)。

你的意思是说你有一台中央计算机需要调用50多台客户端计算机,还是每个客户端计算机都需要调用中央计算机? - MusiGenesis
8个回答

4
WCF不必在IIS中托管,它可以在Winform、控制台应用程序或Windows服务中托管。您可以让每台计算机在其Winform中托管其服务,并编写一个程序在您自己的计算机上调用每台计算机的服务以获取状态信息。
另一种方法是在您自己的计算机上托管一个服务,并使50多台计算机在其状态更新后调用该服务,您可以使用数据库来持久化网络中每个节点的状态数据。这种选择更容易维护和扩展。
附注: WCF旨在取代.net remoting,替代方案可以是net.tcp绑定或net.pipe。

2
除非您计划将其扩展到数千个客户端,否则我认为WCF性能甚至不会成为边缘问题。 您可以轻松地从Windows服务或Winforms应用程序中托管WCF服务,并且一旦掌握了关键概念,使用WCF实现某些功能将变得相当简单。
我已经成功部署了大约100-150个客户端类似的东西。
网络上有很多资源可供您开始使用 - 这是其中之一:

http://msdn.microsoft.com/en-us/library/aa480190.aspx


2
无论您在中央服务器上使用Web服务还是WCF,您只需要在服务器上安装和配置IIS(而不是在50多个客户端上安装)。
从问题中不太清楚您要做什么,但如果客户端需要调用服务器(例如获取服务器状态),则它们只需调用运行在服务器上的Web服务的方法即可。
如果相反,您需要定期让服务器调用客户端,则每个客户端都需要在启动时调用服务器Web服务的登录方法。登录方法将以客户端的委托方法作为参数。然后,当服务器需要来自客户端的信息时,它会调用此委托。
为每个客户端设置自己的Web服务将代表传统的(一个服务器,多个客户端)客户/服务器架构的倒置,正如您已经注意到的那样,这是不切实际的。

2

不要使用远程调用。

如果你想要稳健性和可扩展性,那么你最终只能排除除了基本上是无状态的远程过程调用之外的所有东西。由于这正是 web 服务的能力所在,而且 web 服务更简单、更易于构建,因此远程调用是一种基本上毫无意义的技术。

带有远程委托的回调在性能/可靠性禁止列表中,因此如果你打算为此使用远程调用,请再考虑一下。

使用 web 服务。

我知道你不想进行轮询,但我认为你不需要这样做。既然你说所有的单位都在一个网络段上,那么我建议使用 UDP 进行广播更改通知,基本上设置一个脏标志,并允许应用程序按需(重新)获取。它仍然不可靠,但因为它是广播,所以非常容易和快速。

正如其他人所说,你不需要 IIS,你可以自己托管。请参见ServiceHost 类,了解如何执行此操作的详细信息。


1
我建议使用.NET Remoting。它非常容易实现,不需要任何其他东西。

是的,如果目标框架是在Windows上的.NET,则必须使用.NET Remoting。 - milot

0

作为一个已经为500多个客户实现了类似功能的人:

消息队列是最好的选择。

我们从内部开发的TCP服务器和客户端转向了WCF轮询,最终采用了消息队列。这是唯一可以保证在互联网上将数据传输到客户端和服务器之间的方法。作为额外的奖励,许多这样的解决方案都有一个广泛的框架,使得实现发布-订阅、单向发送、点对点发送、请求-响应变得非常简单。虽然使用WCF也可以实现其中的一些,但这需要大量的时间和精力,还要喝掉无数杯咖啡。

几个重要的注意事项:

让一个进程轮询客户端而不是反过来 = 不好的想法...这根本不可扩展,当进程花费太长时间完成时,很快就会遇到麻烦...更不用说处理所有的IP地址(您是否可以访问所需端口上的所有客户端?当IP地址发生变化时会发生什么等等)。

我们所做的事情:客户端定期向中央消息队列发送状态更新(您可以轻松地在UI中实现实时更新),它还在自己的队列上侦听GetStatusRequest消息。如果收到此消息,它会回答(有超时)...这样,我们可以随时查看所有客户端的总体状态,并在需要时获取特定客户端的特定状态。
关于带宽:亭子通常显示图像/视频等... 1Kb或更少的状态消息不会是大开销。
我无法强调当前设计将具有非常密集的开发周期并且不会很好地扩展和扩展(相信我,我们已经吸取了这个教训)。除此之外,为此类东西构建良好的客户端/服务器协议是一项困难的工作,如果出现设计错误,则完全没有用处(迁移协议并不容易)
我们已经在ActiveMQ之上构建了我们的解决方案(使用NMS库c#),目前正在扩展Simple Service Bus以进行内部工作。
我们仅在我们的WinForms应用程序与集中式服务之间的通信中使用WCF。

0

对我来说,学习网络编程或手动套接字通信更好。Web服务由于包含元数据而速度较慢。

您的客户端和服务器可以转换为多线程应用程序。只需模仿请求和响应架构即可。像这样实现网络应用程序要容易得多。


0

如果您只需要状态更新,可以使用更简单的解决方案,例如简单的tcp服务器/客户端消息传递或像orrsella所说的远程处理。在这里,WCF有点过度。

但请注意,如果您的50多个信息亭都通过互联网连接,则可能需要使用VPN或在每个信息亭上开放一个端口(这是一种安全风险),以便您的服务器可以从每个信息亭检索状态更新。

我们遇到了类似的情况,但状态定期发送到我们的服务器,因此我们只需要保护/安全1个端口。更新的频率是可配置的,以适应较慢的客户端。


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