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运行结果