WCF全雙工通信實例分享(wsDualHttpBinding、netTcpBinding兩種實現方式)


  最近在研究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方式的通信案例,因為其他的我自己沒實際測試過,不敢誤導大家。

 

wsDualHttpBinding實現全雙工

一、服務器端

1、創建WCF服務

自動生成IMyWCFBothway.cs與MyWCFBothway.cs

 

2、編寫服務契約接口

1 [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ICallBack))] 
2     public interface IMyWCFBothway
3     {
4         [OperationContract]
5         string DoWork(string msg);
6     }

 注:

1、CallbackContract = typeof(ICallBack))即為聲明回調契約為ICallBack

2、[OperationContract]如不聲明則客戶端引用服務時對該接口函數不可見

 

3、編寫回掉契約接口

 

1   public interface ICallBack
2     {
3         [OperationContract(IsOneWay = true)]
4         void ClientCallBack(string msg);
5     }

 

注:
1、[OperationContract(IsOneWay = true)] 聲明單向后該接口函數不支持輸出,即不能設置返回值和ref/out傳入引用
2、該接口服務器端不需實現,但需要在客戶端實現

4、實現服務契約接口

 

 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     }

 

 

 

注:
1、如需回調客戶端函數,需要使用OperationContext.Current.GetCallbackChannel<T> 獲取客戶端實現回調接口實例

 

5、修改配置文件

 

 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>



注:
1、主要修改使用的方式改為wsDualHttpBinding

2、http://localhost:8733/Design_Time_Addresses/WCFServer/MyWCFBothway/ 就為客戶端服務引用的鏈接

3、本地測試可以使用localhost,如發布服務器需改為服務器IP

4、端口修改有時會報權限不足,可以將VS用管理員權限打開再編譯

6、啟動服務

1 ServiceHost host1 = new ServiceHost(typeof(WCFServer.MyWCFBothway));
2 host1.Open();

 

二、客戶端

1、引用WCF服務

通過服務引用引用WCF服務:http://localhost:8733/Design_Time_Addresses/WCFServer/MyWCFBothway/

2、實現回調契約接口

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     }
注:
1、實現的回調接口為IMyWCFBothwayCallback,而不是服務器聲明的ICallBack,可以在引用服務后使用對象查看器查看,中間應該是經過代理把名稱統一換了
2、需要聲明
[CallbackBehavior(UseSynchronizationContext = false)],否則回調回失敗,感覺像找不到回調函數還是阻塞了就超時了

 

3、訪問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>  

主要修改的是配置文件:

1、serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" 可能是不使用Http協議的原因,這兩個選項要置為false

2、binding="netTcpBinding"要指定netTcpBinding方式

3、binding="mexTcpBinding"指定使用Tcp方式

4、net.tcp://localhost:8732/Design_Time_Addresses/WCFServer/WCFNetTcp/" 要將前綴聲明為net.tcp協議

 

  其余部分的實現和wsDualHttpBinding方式基本相同~

 

 

  這次測試了這兩種全雙工方式的WCF通信,感覺WCF還是很強大方便的,但是還有很多參數不大清楚,只是使用的默認參數,還需繼續去研究。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM