介紹
WCF(Windows Communication Foundation) - 消息處理:通過操作契約的IsOneWay參數實現異步調用,基於Http, TCP, Named Pipe, MSMQ的雙向通訊。
示例(異步調用OneWay)
1、服務
IOneWay.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace WCF.ServiceLib.Message { /**//// <summary> /// IOneWay接口 /// </summary> [ServiceContract] public interface IOneWay { /**//// <summary> /// 不使用OneWay(同步調用) /// </summary> [OperationContract] void WithoutOneWay(); /**//// <summary> /// 使用OneWay(異步調用) /// </summary> [OperationContract(IsOneWay=true)] void WithOneWay(); } }
OneWay.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace WCF.ServiceLib.Message { /**//// <summary> /// OneWay類 /// </summary> public class OneWay : IOneWay { /**//// <summary> /// 不使用OneWay(同步調用) /// 拋出Exception異常 /// </summary> public void WithoutOneWay() { throw new System.Exception("拋出Exception異常"); } /**//// <summary> /// 使用OneWay(異步調用) /// 拋出Exception異常 /// </summary> public void WithOneWay() { throw new System.Exception("拋出Exception異常"); } } }
2、宿主
OneWay.cs
using (ServiceHost host = new ServiceHost(typeof(WCF.ServiceLib.Message.OneWay))) { host.Open(); Console.WriteLine("服務已啟動(WCF.ServiceLib.Message.OneWay)"); Console.WriteLine("按<ENTER>停止服務"); Console.ReadLine(); }
App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <!--name - 提供服務的類名--> <!--behaviorConfiguration - 指定相關的行為配置--> <service name="WCF.ServiceLib.Message.OneWay" behaviorConfiguration="MessageBehavior"> <!--address - 服務地址--> <!--binding - 通信方式--> <!--contract - 服務契約--> <endpoint address="" binding="basicHttpBinding" contract="WCF.ServiceLib.Message.IOneWay" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://localhost:12345/Message/OneWay/"/> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior name="MessageBehavior"> <!--httpGetEnabled - 使用get方式提供服務--> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
3、客戶端
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using System.ServiceModel; namespace Client2.Message { /**//// <summary> /// 演示Message.OneWay的類 /// </summary> public class OneWay { /**//// <summary> /// 調用IsOneWay=true的操作契約(異步操作) /// </summary> public void HelloWithOneWay() { try { var proxy = new MessageSvc.OneWay.OneWayClient(); proxy.WithOneWay(); proxy.Close(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } /**//// <summary> /// 調用IsOneWay=false的操作契約(同步操作) /// </summary> public void HelloWithoutOneWay() { try { var proxy = new MessageSvc.OneWay.OneWayClient(); proxy.WithoutOneWay(); proxy.Close(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } } }
App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <client> <!--address - 服務地址--> <!--binding - 通信方式--> <!--contract - 服務契約--> <endpoint address="http://localhost:12345/Message/OneWay/" binding="basicHttpBinding" contract="MessageSvc.OneWay.IOneWay" /> </client> </system.serviceModel> </configuration>
運行結果:
單擊"btnWithOneWay"按鈕,沒有彈出提示框。(異步操作)
單擊"btnWithoutOneWay"按鈕,彈出錯誤提示框。(同步操作)
示例(雙向通訊Duplex)
1、服務
IDuplex.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace WCF.ServiceLib.Message { /**//// <summary> /// IDuplex接口 /// </summary> /// <remarks> /// CallbackContract - 回調接口 /// </remarks> [ServiceContract(CallbackContract = typeof(IDuplexCallback))] public interface IDuplex { /**//// <summary> /// Hello /// </summary> /// <param name="name">名字</param> [OperationContract(IsOneWay = true)] void HelloDuplex(string name); } /**//// <summary> /// IDuplex回調接口 /// </summary> public interface IDuplexCallback { /**//// <summary> /// Hello /// </summary> /// <param name="name"></param> [OperationContract(IsOneWay = true)] void HelloDuplexCallback(string name); } }
Duplex.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace WCF.ServiceLib.Message { /**//// <summary> /// Duplex類 /// </summary> public class Duplex : IDuplex { /**//// <summary> /// Hello /// </summary> /// <param name="name">名字</param> public void HelloDuplex(string name) { // 聲明回調接口 IDuplexCallback callback = OperationContext.Current.GetCallbackChannel<IDuplexCallback>(); // 調用回調接口中的方法 callback.HelloDuplexCallback(name); } } }
2、宿主
Duplex.cs
using (ServiceHost host = new ServiceHost(typeof(WCF.ServiceLib.Message.Duplex))) { host.Open(); Console.WriteLine("服務已啟動(WCF.ServiceLib.Message.Duplex)"); Console.WriteLine("按<ENTER>停止服務"); Console.ReadLine(); }
App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <!--name - 提供服務的類名--> <!--behaviorConfiguration - 指定相關的行為配置--> <service name="WCF.ServiceLib.Message.Duplex" behaviorConfiguration="MessageBehavior"> <!--address - 服務地址--> <!--binding - 通信方式--> <!--contract - 服務契約--> <!--雙向通訊可以基於Http, TCP, Named Pipe, MSMQ;其中基於Http的雙向通訊會創建兩個信道(Channel),即需要創建兩個http連接--> <!--endpoint address="Message/Duplex" binding="wsDualHttpBinding" contract="WCF.ServiceLib.Message.IDuplex" /--> <endpoint address="Message/Duplex" binding="netTcpBinding" contract="WCF.ServiceLib.Message.IDuplex" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://localhost:12345/Message/Duplex"/> <add baseAddress="net.tcp://localhost:54321/"/> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior name="MessageBehavior"> <!--httpGetEnabled - 使用get方式提供服務--> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
3、客戶端
Duplex.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; using System.Windows.Forms; namespace Client2.Message { /**//// <summary> /// 演示Message.Duplex的類 /// </summary> public class Duplex { /**//// <summary> /// Hello /// </summary> /// <param name="name">名字</param> public void HelloDulex(string name) { var ct = new Client2.Message.CallbackType(); var ctx = new InstanceContext(ct); var proxy = new MessageSvc.Duplex.DuplexClient(ctx); proxy.HelloDuplex(name); } } }
CallbackType.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; namespace Client2.Message { /**//// <summary> /// 實現回調接口 /// </summary> public class CallbackType : MessageSvc.Duplex.IDuplexCallback { /**//// <summary> /// Hello /// </summary> /// <param name="name">名字</param> public void HelloDuplexCallback(string name) { MessageBox.Show("Hello: " + name); } } }
App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <client> <!--address - 服務地址--> <!--binding - 通信方式--> <!--contract - 服務契約--> <!--endpoint address="http://localhost:12345/Message/Duplex/" binding="wsDualHttpBinding" contract="MessageSvc.Duplex.IDuplex" /--> <endpoint address="net.tcp://localhost:54321/Message/Duplex" binding="netTcpBinding" contract="MessageSvc.Duplex.IDuplex" /> </client> </system.serviceModel> </configuration>
運行結果:
單擊"btnDuplex"按鈕後彈出提示框,顯示"Hello: webabcd"
OK