WCF

一、WCF的基础概念

      WCF的几个重要基础概念如下:

 1.地址

    地址指定了接受消息的位置,WCF中的地址以统一资源标识符(URL)的形式定义。URL由通信协议和位置两部分组成。如http://localhost:8000/ 表明通信协议为http,位置是localhost(本机)的8000端口.

    WCF中支持的传输协议包括HTTP、TCP、IPC(基于命名管道的内部进程通信)、MSMQ(微软消息队列)以及Peer network(对等网),它们对应的地址类型如下:

    HTTP地址:使用HTTP协议进行传输,其地址形式为:http://localhost:8000/

    TCP地址:使用TCP协议进行传输,其地址形式为:net.tcp://localhost:8000/

    IPC地址:使用net.pipe进行传输,其地址形式为:net.pipe://localhost/

    MSMQ地址:使用Micorsoft Message Queue机制进行传输,其定制形式为net.msmq://localhost/

    对等网地址:使用net.p2p进行传输,其地址形式为net.p2p://localhost

2.绑定(Binding)

   由于WCF支持HTTP、TCP、Named Pipe、MSMQ、Peer-To-Peer TCP 等协议,HTTP又分为基本HTTP支持(BasicHttpBinding)以及WS-HTTP支持(WsHttpBinding),而TCP又支持NetTcpBinding,

   NetPeerTcpBing等通信方式,因此双方必须要统一通信的协议,并且要在编码以及格式上保持一致。

   WCF的服务可以挂载于Console Application、WindowsApplication、IIS(ASP.Net) Application、Windows Wervice以及Windows Activation Services中,但大多数都会挂在Windows Service。

主要的系统内置绑定如下:

3.契约(Contract)

  WCF的基本概念是以契约(Contract)来沟通双方的协议,契约必须以接口的方式来体现,而实际的服务代码必须要由这些契约接口派生实现。契约可分为以下四种:

   服务契约(ServiceContract):指定服务的定义

   数据契约(DataContract):指定双方沟通时的数据格式

   操作契约(DataContract):指定服务提供的方法

   消息契约(MessageContract):指定在通信期间改写消息内容的规范

 一个WCF的契约如图下列代码所示:

       [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
        public interface ICalculator
        {
            [OperationContract]
            double Add(double n1, double n2);
            [OperationContract]
            double Subtract(double n1, double n2);
            [OperationContract]
            double Multiply(double n1, double n2);
            [OperationContract]
            double Divide(double n1, double n2);
        }

4.终结点

5.元数据

  所谓“元数据”就是描述数据的数据,即描述当前服务有哪些服务契约,方法契约和数据契约以及终结点信息。当客户端添加WCF服务引用的时候会首先通过元数据取得服务端的契约信息,

  终结点信息,然后通过这些信息在客户端创建代理类。

6.宿主

  一种应用程序或者进程,服务将在该环节下运行。

二、创建一个WCF程序

   1.新建一个空解决方案WCFService,选择“新建项目->类库”,这里不直接创建WCF服务,而是创建一个类库,命名为MyService

   2.添加System.ServiceModel程序集引用

3.新建一个接口ICalculator,引入System.ServiceModel命名空间

    [ServiceContract]
    public  interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);

        [OperationContract]
        double Subtract(double n1, double n2);

        [OperationContract]
        double Multiply(double n1, double n2);

        [OperationContract]
        double Divide(double n1, double n2);

    }

 4.添加Calculator类实现ICalculator接口:

 public class Calculator : ICalculator
    {
        public double Add(double n1, double n2)
        {
            return n1 + n2;
        }

        public double Divide(double n1, double n2)
        {
            return n1 / n2;
        }

        public double Multiply(double n1, double n2)
        {
            return n1 * n2;
        }

        public double Subtract(double n1, double n2)
        {
            return n1 - n2;
        }
    }

5.新建宿主,选择“新建项目->控制台应用程序”,并命名为MyServiceHost

6.添加System.ServiceModel引用和项目引用MyService

7.新建一个MyHost类用来创建ServiceHost对象

 public class MyHost : IDisposable
    {
        /// <summary>
        /// 定义一个服务宿主对象
        /// </summary>
        private ServiceHost _myHost;

        public const string BaseAddress = "net.pipe://localhost";//基地址
        public const string CalculatorServiceAddress = "Calculator";//可选地址

        public static readonly Type ServiceType = typeof(MyService.Calculator);//服务契约实现类型
        public static readonly Type ContractType = typeof(MyService.ICalculator);//服务契约接口类型
        public static readonly Binding MyBinding = new NetNamedPipeBinding();//定义一个绑定

        public MyHost()
        {
            CreateMyServiceHost();
        }

        /// <summary>
        /// 创建服务宿主对象
        /// </summary>
        protected void CreateMyServiceHost()
        {
            _myHost = new ServiceHost(ServiceType, new Uri[] { new Uri(BaseAddress) });//创建服务对象
            _myHost.AddServiceEndpoint(ContractType, MyBinding, CalculatorServiceAddress);//添加终结点
        }

        /// <summary>
        /// 开启服务
        /// </summary>
        public void Open()
        {
            Console.WriteLine("开始启动服务...");
            _myHost.Open();
            Console.WriteLine("服务已经启动...");
        }

        /// <summary>
        /// 销毁服务宿主对象
        /// </summary>
        public void Dispose()
        {
            if(_myHost != null)
            {
                (_myHost as IDisposable).Dispose();
            }
        }
    }

    在Main函数中调用:

class Program
    {
        static void Main(string[] args)
        {
            using (MyHost host = new MyHost())
            {
                host.Open();
                Console.ReadKey();
            }
        }
    }

 8.创建客户端调用程序,选择“新建项目->控制台应用程序”,并命名为MyClient,添加MyService引用

9.添加CalculatorProxy代理类

 public class CalculatorProxy: ClientBase<ICalculator>,ICalculator
    {
        public static readonly Binding MyBinding = new NetNamedPipeBinding();//定义一个绑定
        //主要这里要和服务宿主里定义的地址保持一致
        public static readonly EndpointAddress CalculatorAddress = new EndpointAddress(new Uri("net.pipe://localhost/Calculator"));//地址

        public CalculatorProxy():base(MyBinding, CalculatorAddress)
        {
         
        }

        public double Add(double n1, double n2)
        {
            return Channel.Add(n1,n2);
        }

        public double Subtract(double n1, double n2)
        {
            return Channel.Subtract(n1, n2);
        }

        public double Multiply(double n1, double n2)
        {
            return Channel.Multiply(n1, n2);
        }

        public double Divide(double n1, double n2)
        {
            return Channel.Divide(n1, n2);
        }
    }

  在Main方法中调用:

    class Program
    {
        static void Main(string[] args)
        {
            using (CalculatorProxy proxy = new CalculatorProxy())
            {
                Console.WriteLine("10+5={0}",proxy.Add(10,5));
                Console.WriteLine("10-5={0}", proxy.Subtract(10, 5));
                Console.WriteLine("10*5={0}", proxy.Multiply(10, 5));
                Console.WriteLine("10/5={0}", proxy.Divide(10, 5));
            }
            Console.ReadKey();
        }
    }

10.运行MyServiceHost.exe,如下图:

11.运行MyClient.exe,如下图:

原文地址:https://www.cnblogs.com/marshhu/p/6824591.html