走在WCF学习的路上---印在脑子里的点点滴滴(WCF TCP协议通信的端口共享)
<bindings>
<netTcpBinding>
<binding name="portSharingBinding" portSharingEnabled="true" />
</netTcpBinding>
</bindings>
增加这个即可
一、 端口共享在WCF中的意义何在?
在一般的网络环境中,尽可能避免网络攻击,都会通过防火墙将绝大部分的端口封掉,仅仅保留那些常用的网络服务所用的端口,或者为某一个类应用保留少量的端口。总而言之,我们不能保证每个跨防火墙通信的应用都具有一个唯一的端口,他们只能共享一个或者少量的几个端口。
对于Intranet内部,为了保证部署于局域网内的其他计算机的网络应用能够与本机进行正常通信,通常会在本机的防火墙中预留一个可用的端口。Intranet内部的主机之间可以使用这些预留的端口通过相应的传输协议,比如TCP、HTTP、Named Pipe等等,进行通信。而对于处于Internet和本地网络之间的防火墙,通常仅仅只有保留80端口,保证基于HTTP的网络通信能够正常进行。
所以,无论是基于Intranet还是Internet,无论是采用何种传输协议,端口共享——让多个网络应用程序使用相同的端口进行通信,都具有重要的现实意义。
对于WCF来讲,当我们将某个服务寄宿于一个进程中,实际上就是通过该进程监听和处理来自客户端的Socket请求。在一般情况下,一个端口被一个监听进行独占使用,也就是说,如何你的主机上部署了若干服务,而这些服务寄宿于不同的应用程序中,对于这种寄宿应用程序来说,监听的端口必须不同。
所以,我们需要通过特殊的途径实现基于WCF寄宿的端口共享。对于采用不同的传输协议,我们有不同的解决方案,对于HTTP协议,我们可以通过IIS的寄宿方式实现端口的共享,对于TCP,.NET Framework3.0提供了一个特殊的Windows服务,Net.TCP Port Sharing Service,帮助我们轻松的实现端口的共享。我们接下来就讨论这种端口共享解决方案。
二、Net.TCP Port Sharing Service
从功能上讲,Net.TCP Port Sharing Service实现了和HTTP.SYS相同的功能:请求的监听和分发(request listening and dispatching)。唯一不同是,HTTP.SYS运行在内核模式(Kernel Mode)下,而Net.TCP Port Sharing Service运行在用户模式(User Mode)下。
WCF对Net.TCP Port Sharing Service提供了原生的支持。Net.TCP Port Sharing Service在WCF的实现原理如下图所示:在Net.TCP Port Sharing Service开启的状态下,如果我们通过两个服务寄宿应用程序分别寄宿两个服务,Service1和Service2,并且它们共享一样的监听端口:8888。实际上,当ServiceHost的Open方法被执行的时候,WCF会将这两个地址,net.tcp://artech.com:8888/service1和net.tcp://artech.com:8888/service2注册到Net.TCP Port Sharing Service中。而对于Net.TCP Port Sharing Service来说,在其内部维护者一个目的地址和进程的列表,在进行目的地址注册的时候,会将这两个地址和对应的服务寄宿地址的匹配关系添加到该列表之中。
当我们的服务客户端,proxy1和proxy2,分别调用service1和service2。当基于他们各自服务调用的socket连接请求抵达artech.com的时候,Net.TCP Port Sharing Service会截获请求消息,并获取目的地址。根据该目的地址,结合内部维护的目的地址和目标进程匹配列表,Net.TCP Port Sharing Service得到对应的目标应用程序,并将请求消息向真正的目标程序进行转发。
三 、基于TCP端口共享的编程
由于WCF下基于TCP的端口共享是建立在Net.TCP Port Sharing Service Windows服务上的。所有安装有.NET Framework3.0的操作系统都具有该Windows服务,但是在默认的情况下,该服务是不可用的。当你第一次使用Net.TCP Port Sharing Service,或者发现该服务被禁用,你需要手工的启用该服务。
注:通过“开始”-〉“控制面板”-〉“管理工具”-〉服务,打开如下图所示的“服务对话框”,然后定位到Net.TCP Port Sharing Service。
在基于TCP的WCF通信中,我们使用NetTcpBinding处理通信的所有细节,这些细节中也包括端口的共享。为此在NetTcpBinding中,定义了一个特殊的属性,PortSharingEnabled,表明是否启动端口共享机制。