最近在研究WCF通讯,若是没有接触过的能够看个人前一篇文章:https://www.cnblogs.com/xiaomengshan/p/11159266.html 主要讲的最基础的basicHttpBinding方式的单工WCF通讯,步骤比较详细,因此本文就只说明关键的细节,详细的步骤操做能够参考前一篇文章,还望理解。本文使用的环境是VS2015,使用的项目都是WPF,如使用Winform、Web项目的可能有些细微的差异,不过原理应该差很少,各位能够本身调试一下。
全双工的方式主要是依靠回调客户端函数的方式实现,能够构造数据包处理接口来实现常规C/S架构,也能够搭建发布/订阅机制的系统,看具体使用了。平时新建的WCF服务默认是basicHttpBinding方式的单工方式,支持全双工的有wsDualHttpBinding、netTcpBinding及mexNamedPipeBinding。wsDualHttpBinding经过创建两条Http协议的方式实现全双工;netTcpBinding使用的net.tcp协议进行通讯;mexNamedPipeBinding采用net.pipe的方式,可是该方式好像只支持同一系统间不一样进程的通讯。固然还支持不少其余的方式,不过每去研究。本文只分享wsDualHttpBinding、netTcpBinding方式的通讯案例,由于其余的我本身没实际测试过,不敢误导你们。html
wsDualHttpBinding实现全双工服务器
1、服务器端架构
一、建立WCF服务tcp
自动生成IMyWCFBothway.cs与MyWCFBothway.cside
二、编写服务契约接口函数
1 [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ICallBack))] 2 public interface IMyWCFBothway 3 { 4 [OperationContract] 5 string DoWork(string msg); 6 }
注:测试
一、CallbackContract = typeof(ICallBack))即为声明回调契约为ICallBackui
二、[OperationContract]如不声明则客户端引用服务时对该接口函数不可见spa
三、编写回掉契约接口代理
1 public interface ICallBack 2 { 3 [OperationContract(IsOneWay = true)] 4 void ClientCallBack(string msg); 5 }
注:
一、[OperationContract(IsOneWay = true)] 声明单向后该接口函数不支持输出,即不能设置返回值和ref/out传入引用
二、该接口服务器端不需实现,但须要在客户端实现
四、实现服务契约接口
1 public class MyWCFBothway : IMyWCFBothway 2 { 3 public string DoWork(string msg) 4 { 5 string Str = msg + "访问服务器成功"; 6 //获取客户端实现回调接口的子类实例 7 ICallBack iCallBack = OperationContext.Current.GetCallbackChannel<ICallBack>(); 8 Console.WriteLine(msg+"访问服务器"); 9 Console.WriteLine(msg + "服务器执行回调"); 10 //执行客户端的回调函数 11 iCallBack.ClientCallBack("服务器执行回调成功"); 12 Console.Read(); 13 return Str; 14 } 15 }
注:
一、如需回调客户端函数,须要使用OperationContext.Current.GetCallbackChannel<T> 获取客户端实现回调接口实例
五、修改配置文件
1 <service name="WCFServer.MyWCFBothway"> 2 <endpoint address="" binding="wsDualHttpBinding" contract="WCFServer.IMyWCFBothway"> 3 <identity> 4 <dns value="localhost" /> 5 </identity> 6 </endpoint> 7 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 8 <host> 9 <baseAddresses> 10 <add baseAddress="http://localhost:8733/Design_Time_Addresses/WCFServer/MyWCFBothway/" /> 11 </baseAddresses> 12 </host> 13 </service> 14 </services>
注:
一、主要修改使用的方式改成wsDualHttpBinding
二、http://localhost:8733/Design_Time_Addresses/WCFServer/MyWCFBothway/ 就为客户端服务引用的连接
三、本地测试可使用localhost,如发布服务器需改成服务器IP
四、端口修改有时会报权限不足,能够将VS用管理员权限打开再编译
六、启动服务
1 ServiceHost host1 = new ServiceHost(typeof(WCFServer.MyWCFBothway)); 2 host1.Open();
2、客户端
一、引用WCF服务
经过服务引用引用WCF服务:http://localhost:8733/Design_Time_Addresses/WCFServer/MyWCFBothway/
二、实现回调契约接口
1 [CallbackBehavior(UseSynchronizationContext = false)] 2 public class MyClientCallBack: IMyWCFBothwayCallback 3 { 4 public void ClientCallBack(string msg) 5 { 6 Console.WriteLine(msg); 7 Console.Read(); 8 } 9 }
注:
一、实现的回调接口为IMyWCFBothwayCallback,而不是服务器声明的ICallBack,能够在引用服务后使用对象查看器查看,中间应该是通过代理把名称统一换了
二、须要声明[CallbackBehavior(UseSynchronizationContext = false)],不然回调回失败,感受像找不到回调函数仍是阻塞了就超时了
三、访问WCF服务
1 //声明回调实现类实例 2 MyClientCallBack CallBack = new MyClientCallBack(); 3 //使用回调实现类实例建立会话实例 4 InstanceContext context = new InstanceContext(CallBack); 5 //建立WCF服务实例,传入会话实例给服务器是为了方便服务器经过该会话进行回调 6 WCFBothway.MyWCFBothwayClient W = new MyWCFBothwayClient(context); 7 //访问WCF服务 8 string msg = W.DoWork("客户端1"); 9 Console.WriteLine(msg); 10 Console.Read();
netTcpBinding实现全双工
其实netTcpBinding方式与wsDualHttpBinding方式用法基本相同,区别只是在一些配置上面,因此下面只说明其中的不一样点就不一步步详细冗余说明了。
服务契约接口实现:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] public class WCFNetTcp : IWCFNetTcp { public string DoWork(string msg) { Console.WriteLine(msg + "访问服务器"); Console.Read(); //获取客户端实现回调接口的子类实例 ICallBackNetTcp iCallBack = OperationContext.Current.GetCallbackChannel<ICallBackNetTcp>(); iCallBack.CallBack("执行回调"); string Str = msg + "访问服务器成功"; return Str; } }
注:这个要声明[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)],否则会报错
App.config:
1 <behaviors> 2 <serviceBehaviors> 3 <behavior name=""> 4 <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" /> 5 <serviceDebug includeExceptionDetailInFaults="false" /> 6 </behavior> 7 </serviceBehaviors> 8 </behaviors> 9 10 <service name="WCFServer.WCFNetTcp"> 11 <endpoint address="" binding="netTcpBinding" contract="WCFServer.IWCFNetTcp"> 12 <identity> 13 <dns value="localhost" /> 14 </identity> 15 </endpoint> 16 <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/> 17 <host> 18 <baseAddresses> 19 <add baseAddress="net.tcp://localhost:8732/Design_Time_Addresses/WCFServer/WCFNetTcp/" /> 20 </baseAddresses> 21 </host> 22 </service>
主要修改的是配置文件:
一、serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" 多是不使用Http协议的缘由,这两个选项要置为false
二、binding="netTcpBinding"要指定netTcpBinding方式
三、binding="mexTcpBinding"指定使用Tcp方式
四、net.tcp://localhost:8732/Design_Time_Addresses/WCFServer/WCFNetTcp/" 要将前缀声明为net.tcp协议
其他部分的实现和wsDualHttpBinding方式基本相同~
此次测试了这两种全双工方式的WCF通讯,感受WCF仍是很强大方便的,可是还有不少参数不大清楚,只是使用的默认参数,还需继续去研究。