WCF概念:

    WCF是 “Windows Communication Foundation ”的缩写,Windows Communication Foundation (WCF) 是一个运行库和一组 API,用于创建在服务与客户端之间发送消息的系统。 它使用相同的基础结构和 API 来创建应用程序,这些应用程序可与同一计算机系统上或驻留在另一家公司内并通过 Internet 访问的系统上的其他应用程序进行通信。

    WCF通过一种面向服务的新型编程模型简化了关联应用程序的开发。通过提供分层的体系结构,WCF 支持多种风格的分布式应用程序开发。 WCF 通道体系结构在底层提供了异步的非类型化消息传递基元。

WCF体系结构图

      

Contract(契约) :

    在WCF中所有需要向外部服务的方法或对象都需要标明契约属性。

    基本契约有4种:

服务契约(Service Contract) :

指示接口或类在Windows Communication Foundation (WCF) 应用程序中定义服务协定。

数据契约(Data Contract) :

指定该类型要定义或实现一个数据协定,并可由序列化程序(如 System.Runtime.Serialization.DataContractSerializer)进行序列化。若要使其类型可序列化,类型作者必须为其类型定义数据协定。

异常契约(Fault Contract):

指定服务操作遇到处理错误时返回的一个或多个 SOAP 错误

消息契约(Message Contract):

定义与 SOAP 消息相对应的强类型类。

 

 

简单WCFService创建:

 

    WCF服务端:

    这里创建一个最简单,以Web形式发布的WCFService,现在这里创建一个“WCF 服务应用程序”名为 “WebWcfServiceA

   

    项目需要System.ServiceModel 与 System.Runtime.Serialization的引用。基本上所有有关于WCF的项目,都会需要到引用这两个组件。

   

    此项目中有一个接口IWebWcfServiceA 用于表示WCF公开的方法。

    [ServiceContract]

    public interface IWebWcfServiceA

    {

        [OperationContract]

        stringserviceFunction(int value);

   }

         这里接口中的契约属性ServiceContract 用于标明这个接口是公开可调用的。

         方法中的契约属性OperationContract 用于标明这个方法是公开可调用的。

   

         除了接口外,还需要一个WCF服务文件,在这里命名为“WebWcfServiceA.svc”。

    public class WebWcfServiceA: IWebWcfServiceA

    {

        public string serviceFunction(intvalue)

        {

            returnstring.Format("Youentered: {0}", value);

        }

   }

         这个类是WCF的主体,它继承于WCF公开的接口并完成接口的功能。

   

   

         这里需要注意的是,所有对接口ServiceContract 和服务文件WebWcfServiceA.svc进行过名称更改的,都需要在配置文件中进行相应的更改。

       在配置文件中的 <system.serviceModel>节里面说明了WCF相关的配置,在这里需要注意的是元素service endpoint service name 属性指名了WCF 服务类的位置;endpointcontract 属性指名了契约接口的位置。

客户端:

         现在为这个简单的WCFService创建一个简单的客户端,控制台程序“WebWcfAClient”。

   

         最简单创建客户端的办法就是像创建Web Service那样添加一个服务引用,这个服务引用直接指向刚才创建的WebWcfServiceA项目。

         创建成功后,项目会添加一份app.config,此文件记录了关于WCF服务的信息,其中这里需要注意一下的是client 中的 endpointaddress ,这里记录了指向WCF 服务的路径。

         创建这样一个服务引用后,便可以直接调用其中暴露出来的方法。

        static void Main()

        {

           WebWcfServiceA.WebWcfServiceAClientServiceA = new WebWcfAClient.WebWcfServiceA.WebWcfServiceAClient();

            Console.WriteLine(ServiceA.serviceFunction(0));

            Console.ReadKey();

            ServiceA.Close();

       }

    这种客户端方式的调用,基本和webService的调用相似。

第二种WcfService创建:

    因为公开暴露的方法是在接口上,所以除了使用服务引用的办法来创建客户端引用外,还可以通过使用引用该接口的办法来调用WCF的服务。

   

    契约接口:

        

         首先,创建一个接口项目(IWebWcfServiceB)用于服务端和客户端双方的调用:

    [ServiceContract]

    public interface IService

    {

        [OperationContract]

        CompositeTypeserviceFunction(int value);

    }

    [DataContract]

    public class CompositeType

    {

        [DataMember]

        public string strValue

        {

            get;

            set;

        }

   }

这里的CompositeType类的属性DataContract(数据契约)用于标明此类是用在于WCF服务中提供数据的,并且此类是可以序列化的。

         属性strValue上的DataMember属性标明属性strValue可以序列化。

    服务端:

   

    服务段只有一个文件WebWcfServiceB.svc

    public class WebWcfServiceB: IService

    {

        public CompositeType serviceFunction(int value)

        {

            CompositeTypect = new CompositeType();

            ct.strValue = string.Format("Youentered: {0}", value);

            returnct;

        }

   }

    它基本和WebWcfServiceB.svc一致,只是继承的接口被分离到另外一个项目中。

   

    客户端:

   

    客户端需要引用接口IWebWcfServiceB,还需要为接口创建一个代理类,用于调用WCF服务。

    这个接口类可以手工创建,但是你运行打开上述的WebWcfServiceB.svc 文件时候会发现VS提供了一个工具svcutil.exe 来创建这个代理类。

         这里是一个手工写的代理类:

    public partial class ServiceClient : System.ServiceModel.ClientBase<IService>,IService

    {

        publicServiceClient(System.ServiceModel.Channels.Bindingbinding, System.ServiceModel.EndpointAddressremoteAddress) :

            base(binding,remoteAddress)

        {

        }

        public CompositeType serviceFunction(int value)

        {

            returnbase.Channel.serviceFunction(value);

        }

    }

    [DataContractAttribute]

    public partial class CompositeType : object,System.Runtime.Serialization.IExtensibleDataObject

    {

        publicSystem.Runtime.Serialization.ExtensionDataObjectExtensionData

        {

            get;

            set;

        }

        [DataMemberAttribute]

        public string strValue

        {

            get;

            set;

        }

   }

    需要注意的是这里的命名空间要和公开接口的命名空间一致。

    如果使用工具写出的代码会有更多的实现方法,并且工具将会输出一个名为output.config 的文件,此文件和使用服务引用时添加的配置文件一样。

         代理类的使用如下:

            System.ServiceModel.WSHttpBinding binding = newSystem.ServiceModel.WSHttpBinding();

            System.ServiceModel.EndpointAddress address =

                newSystem.ServiceModel.EndpointAddress(new Uri("http://localhost/WebWcfServiceB.svc"));

            ServiceClientServiceB = new ServiceClient(binding,address);

            CompositeTypect = ServiceB.serviceFunction(0);

            Console.WriteLine(ct.strValue);

            Console.ReadKey();

            ServiceB.Close();

         如果是使用配置文件的,可以直接ServiceClient ServiceB = new ServiceClient() 来读取调用配置文件中的路径。

WCF服务库:

          除了使用上面两种以WCF服务文件为主体,依附IIS的创建方式以外,还可以使用WCF服务库来创建WCF服务。

         直接创建一个WCF服务库,可以看见IDE为你创建了三份文件,一个公开契约的接口,一个控制台应用程序的WCF服务主体,和一份配置文件。

         这个结构和之前创建WCF 服务应用程序基本相同,只不过是主体由svc服务文件变为了控制台的应用程序。

         服务端:

    项目名称:HostWcfServiceA

   [ServiceContract]

   public interfaceIService

   {

       [OperationContract]

       string serviceFunction(int value);

    }

   public classHostWcfServiceA : IService

   {

       public stringserviceFunction(int value)

       {

            returnstring.Format("Youentered: {0}", value);

       }

    }

此服务运行后将会根据配置文件中baseAddress属性的地址来监听,该地址只是用于通信,不能使用浏览器打开。

    客户端:

    创建一个新的控制台程序HostWcfAClient 来作为客户端,客户端对此WCF服务的调用也可以使用服务引用,具体调用和WCF服务文件的方式一样。

服务端除了使用配置文件来配置监听路径外,还可以使用代码来配置监听路径,方法是使用另外一个应用程序来作为服务主机,让客户端调用。

    服务端B

    此服务端B的服务库与项目HostWcfServiceA 的服务库一样,添加多一个控制台应用程序作为服务器:

            Uri baseAddress = newUri("http://127.0.0.1:55555");

            using (ServiceHosthost = new ServiceHost(typeof(HostWcfServiceB.HostWcfServiceB),new Uri[] {baseAddress }))

            {

                BasicHttpBinding binding = new BasicHttpBinding();

               host.AddServiceEndpoint(typeof(HostWcfServiceB.IService), binding, baseAddress);

               host.Open();

                Console.WriteLine("服务已启动");

                Console.Read();

            }

 posted on 2010-05-21 16:58  dongpo  阅读(186)  评论(0编辑  收藏  举报