WCF技术剖析(卷1)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.3.4 步骤四 通过自我寄宿的方式寄宿服务

WCF服务须要依存一个运行着的进程(宿主),服务寄宿就是为服务指定一个宿主的过程。WCF是一个基于消息的通信框架,采用基于终结点(Endpoint)的通信手段。终结点由地址(Address)、绑定(Binding)和契约(Contract)三要素组成,如图1-4所示。由于三要素的首字母分别为A、B、C,所以就有了易于记忆的公式:Endpoint = ABC。一个终结点包含了实现通信所必需的所有信息,我们可以这样认识终结点的ABC:

图1-4 终结点三要素

地址(Address):地址决定了服务的位置,解决了服务寻址的问题,第2章提供了对地址和寻址机制的详细介绍。

绑定(Binding):绑定实现了通信的所有细节,包括网络传输、消息编码,以及其他为实现某种功能(比如安全、可靠传输、事务等)对消息进行的相应处理。WCF中具有一系列的系统定义绑定,比如BasicHttpBinding、WsHttpBinding、NetTcpBinding等,第3章提供对绑定的详细介绍。

契约(Contract):契约是对服务操作的抽象,也是对消息交换模式及消息结构的定义。第4章提供对服务契约的详细介绍。

服务寄宿的目的就是开启一个进程,为WCF服务提供一个运行的环境。通过为服务添加一个或多个终结点,使之暴露给潜在的服务消费者。服务消费者最终通过相匹配的终结点对该服务进行调用。我们完全可以通过代码的方式完成所有的服务寄宿工作,下面的代码体现了通过一个控制台应用对CalculatorService的寄宿:

        using System;
        using System.ServiceModel;
        using System.ServiceModel.Description;
        using Artech.WcfServices.Contracts;
        using Artech.WcfServices.Services;
        namespace Artech.WcfServices.Hosting
        {
            class Program
            {
              static void Main(string[] args)
              {
                    using (ServiceHost host = new ServiceHost(typeof
                      (CalculatorService)))
                    {
                        host.AddServiceEndpoint(typeof(ICalculator), new
                          WSHttpBinding(),"http://127.0.0.1:9999/calculatorservice");
                        if (host.Description.Behaviors.Find<ServiceMetadataBehavior>()
                          == null)
                        {
                          ServiceMetadataBehavior behavior =
                              new ServiceMetadataBehavior();
                          behavior.HttpGetEnabled = true;
                          behavior.HttpGetUrl = new Uri("http://127.0.0.1:9999/
                              calculatorservice/metadata");
                          host.Description.Behaviors.Add(behavior);
                        }
                        host.Opened += delegate
                        {
                          Console.WriteLine("CalculaorService已经启动,按任意键终止服务!");
                        };
                        host.Open();
                        Console.Read();
                  }
              }
            }
        }

WCF服务寄宿通过一个特殊的对象完成:ServiceHost。在上面的例子中,基于WCF服务的类型(typeof(CalculatorService))创建了ServiceHost对象,并添加了一个终结点。具体地址为http://127.0.0.1:9999/calculatorservice,采用WsHttpBinding,并指定了服务契约的类型ICalculator。

松耦合是SOA的一个基本的特征,WCF应用中客户端和服务端的松耦合体现在客户端只须要了解WCF服务基本的描述,而无须知道具体的实现细节,就可以实现正常的服务调用。WCF服务的描述通过元数据(Metadata)的形式发布出来。WCF中元数据的发布通过一个特殊的服务行为ServiceMetadataBehavior来实现。在上面提供的服务寄宿代码中,我们为创建的ServiceHost添加了ServiceMetadataBehavior,并采用了基于HTTP-GET的元数据获取方式,元数据的发布地址通过ServiceMetadataBehavior的HttpGetUrl指定。在调用ServiceHost的Open方法对服务成功寄宿后,我们可以通过该地址获取服务相关的元数据。在IE地址栏上键入http://127.0.0.1:9999/calculatorservice/metadata,你将会得到以WSDL形式体现的服务元数据,如图1-5所示。

图1-5 通过HTTP-GET的方式获取WCF服务的元数据

在进行真正的WCF应用开发时,一般不会直接通过编码的方式进行终结点的添加和服务行为的定义,而是通过配置的方式进行。上面添加终结点和定义服务行为的代码可以用下面的配置代替:

        <?xml version="1.0" encoding="utf-8" ?>
        <configuration>
            <system.serviceModel>
              <behaviors>
                  <serviceBehaviors>
                        <behavior name="metadataBehavior">
                            <serviceMetadata httpGetEnabled="true" httpGetUrl=
                              "http://127.0.0.1:9999/calculatorservice/metadata" />
                        </behavior>
                  </serviceBehaviors>
              </behaviors>
              <services>
                  <service behaviorConfiguration="metadataBehavior" name=
                      "Artech.WcfServices.Services.CalculatorService">
                        <endpoint address="http://127.0.0.1:9999/calculatorservice"
                          binding="wsHttpBinding" contract="Artech.WcfServices.
                          Contracts.ICalculator" />
                  </service>
              </services>
            </system.serviceModel>
        </configuration>

对于初学者来说,WCF的配置显得过于复杂,直接对配置文件进行手工编辑不太现实。在这种情况下,可以直接使用VS提供的配置工具。你可以通过VS的工具(Tools)菜单,选择“WCF Service Configuration Editor”子项,开启这样的一个配置编辑器,如图1-6所示。

图1-6 如何获得WCF服务配置编辑器

如果采用了上述的配置,服务寄宿代码将会得到极大的精简,只须包含下面几行代码:

        namespace Artech.WcfServices.Hosting
        {
            class Program
            {
              static void Main(string[] args)
              {
                  using (ServiceHost host =
                      new ServiceHost(typeof(CalculatorService)))
                  {
                        host.Opened += delegate
                        {
                          Console.WriteLine("CalculaorService已经启动,按任意键终止服务!");
                        };
                        host.Open();
                        Console.Read();
                  }
              }
            }
        }