最近在研究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仍是很強大方便的,可是還有不少參數不大清楚,只是使用的默認參數,還需繼續去研究。