Windows Communication Foundation(WCF)是由微軟開發的一系列支持數據通信的應用程序框架,可以翻譯為Windows 通訊開發平台。
WCF整合了原有的windows通訊的 .net Remoting,WebService,Socket的機制,並融合有HTTP和FTP的相關技術。
簡單的歸結為四大部分
1>.網絡服務的協議,即用什么網絡協議開放客戶端接入。
2>.業務服務的協議,即聲明服務提供哪些業務。
3>.數據類型聲明,即對客戶端與服務器端通信的數據部分進行一致化。
4>.傳輸安全性相關的定義。
下面直接看一個例子:
一.服務端實例
1.定義一個WCF接口名稱未Ichangeline
服務契約(ServiceContract),訂定服務的定義。
// 注意: 使用“重構”菜單上的“重命名”命令,可以同時更改代碼和配置文件中的接口名“IStaffLoginCheckService”。
[ServiceContract] //服務協定定義
public interface IChangeline
{
[OperationContract] // 操作服務定義
string EsopCheckOk();
[OperationContract]
string HelloWorld();
}
2.定義一個類實現接口名稱Changeline
// 注意: 使用“重構”菜單上的“重命名”命令,可以同時更改代碼和配置文件中的類名“StaffLoginCheckService”。
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single)]
public class Changeline : IChangeline
{
public string HelloWorld()
{
string result = "123456";
return result;
}
}
3.開通WCF所需要的服務,也可以從VS直接添加WCF服務

1 #region 啟動WCF服務 2 private void OpenWcfService() 3 { 4 try 5 { 6 var changeline = new Changeline(bendview); 7 host = new ServiceHost(changeline, new Uri("http://localhost:8734/MyService/")); 8 //這是我們服務的地址 9 host.AddServiceEndpoint(typeof(IChangeline), new BasicHttpBinding(), string.Empty); 10 host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true }); 11 //mex元數據的地址 12 host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), 13 "mex"); 14 host.Open(); 15 var port = "8734"; //獲取端口號 16 var inname = "Changeline"; //打開端口號的名稱 17 var str = " netsh advfirewall firewall add rule name=" + inname + 18 " dir=in action=allow protocol=TCP localport= " + port; 19 var pro = new Process(); //實例化進程 20 pro.StartInfo.FileName = "cmd.exe"; //設置要運行的程序文件 21 pro.StartInfo.UseShellExecute = false; //是否使用操作系統shell程序啟動 22 pro.StartInfo.RedirectStandardInput = true; //是否接受來自應用程序的調用 23 pro.StartInfo.RedirectStandardOutput = true; //是否接受來自應用程序的輸出信息 24 pro.StartInfo.RedirectStandardError = true; //是否接受重定向錯誤信息 25 pro.StartInfo.CreateNoWindow = true; //不顯示窗口信息 26 pro.Start(); //啟動程序 27 28 //向cmd窗口發送輸入信息 29 pro.StandardInput.WriteLine(str + "&exit"); 30 31 pro.StandardInput.AutoFlush = true; 32 pro.WaitForExit(); //等待程序運行完退出程序 33 pro.Close(); //關閉進程 34 } 35 catch (Exception ex) 36 { 37 Tool.Log.Error("WCF開起失敗:" + ex.Message); 38 } 39 CheckWCFServerTh = new Thread(WCF_HostCheck); 40 CheckWCFServerTh.IsBackground = true; 41 CheckWCFServerTh.Start(); 42 } 43 void WCF_HostCheck(object o) 44 { 45 //Closed 指示通信對象已關閉,且不再可用。 46 //Closing 指示通信對象正轉換到 Closed 狀態。 47 //Created 指示通信對象已實例化且可配置,但尚未打開或無法使用。 48 //Faulted 指示通信對象發生錯誤,無法恢復且不再可用。 49 //Opened 指示通信對象目前已打開,且隨時可供使用。 50 //Opening 指示通信對象正從 Created 狀態轉換到 Opened 狀態。 51 while (true) 52 { 53 try 54 { 55 if (!(host.State == CommunicationState.Opened || host.State == CommunicationState.Opening)) 56 { 57 var changeline = new Changeline(bendview); 58 host = new ServiceHost(changeline, new Uri("http://localhost:8734/MyService/")); 59 //這是我們服務的地址 60 host.AddServiceEndpoint(typeof(IChangeline), new BasicHttpBinding(), string.Empty); 61 host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true }); 62 //mex元數據的地址 63 host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), 64 "mex"); 65 host.Open(); 66 67 var port = "8734"; //獲取端口號 68 var inname = "Changeline"; //打開端口號的名稱 69 var str = " netsh advfirewall firewall add rule name=" + inname + 70 " dir=in action=allow protocol=TCP localport= " + port; 71 var pro = new Process(); //實例化進程 72 pro.StartInfo.FileName = "cmd.exe"; //設置要運行的程序文件 73 pro.StartInfo.UseShellExecute = false; //是否使用操作系統shell程序啟動 74 pro.StartInfo.RedirectStandardInput = true; //是否接受來自應用程序的調用 75 pro.StartInfo.RedirectStandardOutput = true; //是否接受來自應用程序的輸出信息 76 pro.StartInfo.RedirectStandardError = true; //是否接受重定向錯誤信息 77 pro.StartInfo.CreateNoWindow = true; //不顯示窗口信息 78 pro.Start(); //啟動程序 79 //向cmd窗口發送輸入信息 80 pro.StandardInput.WriteLine(str + "&exit"); 81 pro.StandardInput.AutoFlush = true; 82 pro.WaitForExit(); //等待程序運行完退出程序 83 pro.Close(); //關閉進程 84 } 85 } 86 catch (Exception ex) 87 { 88 Tool.Log.Error("WCF開起失敗:" + ex.Message); 89 } 90 Thread.Sleep(3000); 91 } 92 } 93 #endregion
二.客戶端的程序
1.配置好通道工廠,為客戶端創立獨立通道,為獲取接口配置程序可以創建一個類(WcfChannelFactory)

1 /// <summary> 2 /// 使用ChannelFactory為wcf客戶端創建獨立通道 3 /// </summary> 4 public class WcfChannelFactory 5 { 6 public WcfChannelFactory() 7 { 8 } 9 10 /// <summary> 11 /// 執行方法 WSHttpBinding 12 /// </summary> 13 /// <typeparam name="T">服務接口</typeparam> 14 /// <param name="uri">wcf地址</param> 15 /// <param name="methodName">方法名</param> 16 /// <param name="args">參數列表</param> 17 public static object ExecuteMetod<T>(string uri, string methodName, params object[] args) 18 { 19 //BasicHttpBinding binding = new BasicHttpBinding(); 20 WSHttpBinding binding = new WSHttpBinding(); 21 EndpointAddress endpoint = new EndpointAddress(uri); 22 23 using (ChannelFactory<T> channelFactory = new ChannelFactory<T>(binding, endpoint)) 24 { 25 T instance = channelFactory.CreateChannel(); 26 using (instance as IDisposable) 27 { 28 try 29 { 30 Type type = typeof(T); 31 MethodInfo mi = type.GetMethod(methodName); 32 return mi.Invoke(instance, args); 33 } 34 catch (TimeoutException) 35 { 36 (instance as ICommunicationObject).Abort(); 37 throw; 38 } 39 catch (CommunicationException) 40 { 41 (instance as ICommunicationObject).Abort(); 42 throw; 43 } 44 catch (Exception vErr) 45 { 46 (instance as ICommunicationObject).Abort(); 47 throw; 48 } 49 } 50 } 51 } 52 53 54 //nettcpbinding 綁定方式 55 public static object ExecuteMethod<T>(string pUrl, string pMethodName,params object[] pParams) 56 { 57 EndpointAddress address = new EndpointAddress(pUrl); 58 Binding bindinginstance = null; 59 BasicHttpBinding ws = new BasicHttpBinding(); 60 ws.MaxReceivedMessageSize = 20971520; 61 bindinginstance = ws; 62 using (ChannelFactory<T> channel = new ChannelFactory<T>(bindinginstance, address)) 63 { 64 T instance = channel.CreateChannel(); 65 using (instance as IDisposable) 66 { 67 try 68 { 69 Type type = typeof(T); 70 MethodInfo mi = type.GetMethod(pMethodName); 71 return mi.Invoke(instance, pParams); 72 } 73 catch (TimeoutException) 74 { 75 (instance as ICommunicationObject).Abort(); 76 throw; 77 } 78 catch (CommunicationException) 79 { 80 (instance as ICommunicationObject).Abort(); 81 throw; 82 } 83 catch (Exception vErr) 84 { 85 (instance as ICommunicationObject).Abort(); 86 throw; 87 } 88 } 89 } 90 } 91 }
2.調用WcfChannelFactory,獲取接口數據
調用時需要把服務端開的接口添加到本程序中,

public void Statedeal() { try { string result = WcfChannelFactory.ExecuteMethod<IChangeline>("http://localhost:8734/MyService/", "EsopCheckOk").ToString(); MessageBox.Show(result.ToString()); } catch(Exception ex) { MessageBox.Show(ex.ToString()); } }
此時整個的服務端與客戶端都可以實現了,如果客戶端程序中也含有wcf服務程序(也會發布WCF服務,也作為服務端),並且接口名稱與服務端(本客戶端的服務端)的接口名稱相同,那就必須保證服務端提供的接口名稱與客戶端定義的接口名稱不同,或者相同名稱在不同的程序集下。