WCF( Windows Communication Foundation), 是Microsoft爲構建面向服務的應用提供的分佈式通訊編程框架,是.NET Framework 3.5的重要組成部分。使用該框架,開發人員能夠構建跨平臺、安全、可靠和支持事務處理的企業級互聯應用解決方案。編程
簡單的說:WCF就是分佈式通訊框架。 安全
Endpoint框架
Endpoint是WCF實現通訊的核心要素。一個WCF Service由一個Endpoint集合組成,每一個Endpoint就是用於通訊的入口,客戶端和服務端經過Endpoint交換信息。
Endpoint由三部分組成:Address,Binding,Contract。便於記憶,咱們每每將這三部分稱爲是WCF的ABC。
Address分佈式
Address經過一個URI惟一地標識一個Endpoint,並告訴潛在的WCF service的調用者如何找到這個Endpoint。ide
Binding測試
Binding實如今Client和Service通訊的全部底層細節。好比Client與Service之間傳遞的Message是如何編碼的—— text/XML, binary,MTOM;這種Message的傳遞是採用的哪一種Transport——TCP, Http, Named Pipe, MSMQ; 以及採用怎樣的機制解決Secure Messaging的問題——SSL,Message Level Security。因此Binding解決的是How to communicate with service?編碼
Contractspa
Contract的主要的做用是定義通訊協議,具體Service提供了哪些方法。code
Behaviorblog
Behavior: Behavior的主要做用是定製Endpoint在運行時的一些必要的Behavior。好比Service回調Client的Timeout;Client採用的Credential type;以及是否支持Transaction等。
(1)、定義服務協定。 服務協定指定服務的簽名、服務交換的數據和其餘協定要求的數據
(2)、實現協定。 若要實現服務協定,請建立實現協定的類並指定運行時應具備的自定義行爲。
(3)、經過指定終結點和其餘行爲信息來配置服務
(4)、承載服務
(5)、生成客戶端應用程序。
經過最簡單的計算器功能來解釋具體的實現過程
1)首先定義契約,這個協議就是定義通訊接口
/// <summary> /// 計算協議 /// </summary> [ServiceContract(Namespace = "http://www.yank.com/")] public interface ICalculator { /// <summary> /// 加 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> [OperationContract] double Add(double x, double y); /// <summary> /// 減 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> [OperationContract] double Subtract(double x, double y); /// <summary> /// 乘 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> [OperationContract] double Multiply(double x, double y); /// <summary> /// 除 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> [OperationContract] double Divide(double x, double y); }
2)經過具體類實現接口功能
/// <summary> /// 計算器具體實現 /// </summary> public class CalculatorService : ICalculator { /// <summary> /// 加 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public double Add(double x, double y) { return x + y; } /// <summary> /// 減 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public double Subtract(double x, double y) { return x - y; } /// <summary> /// 乘 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public double Multiply(double x, double y) { return x * y; } /// <summary> /// 除 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public double Divide(double x, double y) { return x / y; } }
3)根據契約(Contract),綁定(Binding)和地址(Address),建立服務節點(ServiceEndPoint)
4)將服務節點承載在主機(Host)中,例子將host承載在一個控制檯程序中。
#region 採用代碼方式實現對契約的綁定 Uri baseAddress = new Uri("http://127.0.0.1:9999/"); using (ServiceHost host = new ServiceHost(typeof(CalculatorService), baseAddress)) { //使用指定的協定、綁定和終結點地址將服務終結點添加到承載服務中 host.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), "CalculatorService"); #region Behavior ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); behavior.HttpGetEnabled = true; behavior.HttpGetUrl = new Uri("http://127.0.0.1:9999/CalculatorService/metadata"); host.Description.Behaviors.Add(behavior); #endregion host.Opened += delegate { Console.WriteLine("CalculaorService已經啓動,按任意鍵終止服務!"); }; host.Open(); Console.Read(); } #endregion
5)客戶端調用,經過Channel方式調用
namespace ClientWithChannel { class Program { static void Main(string[] args) { using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(new WSHttpBinding(), "http://127.0.0.1:9999/CalculatorService")) { ICalculator proxy = channelFactory.CreateChannel(); using (proxy as IDisposable) { Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2)); Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2)); Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2)); Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2)); Console.ReadLine(); } } } } }
6)運行Host的Console程序,將服務啓動,進行監聽,而後啓動客戶端程序測試調用。
Host啓動
Client運行結果