官术网_书友最值得收藏!

1.3.5 步驟五 創(chuàng)建客戶端調(diào)用服務(wù)

服務(wù)被成功寄宿后,服務(wù)端便開始了服務(wù)調(diào)用請求的監(jiān)聽工作。此外,服務(wù)寄宿將服務(wù)描述通過元數(shù)據(jù)的形式發(fā)布出來,相應(yīng)的客戶端就可以獲取這些元數(shù)據(jù),創(chuàng)建客戶端程序進(jìn)行服務(wù)的消費(fèi)。在VS下,當(dāng)我們添加服務(wù)引用的時候,VS在內(nèi)部幫我們實(shí)現(xiàn)元數(shù)據(jù)的獲取,并借助這些元數(shù)據(jù)通過代碼生成工具(SvcUtil.exe)自動生成用于服務(wù)調(diào)用的服務(wù)代理相關(guān)代碼和相應(yīng)的配置。

在運(yùn)行服務(wù)寄宿程序(Hosting.exe)的情況下,右鍵點(diǎn)擊Client項(xiàng)目,在彈出的上下文菜單中選擇“添加服務(wù)引用(Add Service References)”,如圖1-7所示的添加服務(wù)引用的對話會顯示出來。在地址欄上鍵入服務(wù)元數(shù)據(jù)發(fā)布的源地址:http://127.0.0.1:9999/calculatorservice/metadata,并指定一個命名空間,點(diǎn)擊OK按鈕,VS為你生成一系列用于服務(wù)調(diào)用的代碼和配置。

圖1-7 添加服務(wù)引用

在一系列自動生成的類中,包含一個服務(wù)契約接口、一個服務(wù)代理對象和其他相關(guān)的類。被客戶端直接用于服務(wù)調(diào)用的是一個繼承自ClientBase<CalculatorService>并實(shí)現(xiàn)了CalculatorService接口(CalculatorService為客戶端生成的服務(wù)契約接口類型)的服務(wù)代理類。ClientBase<CalculatorService>的定義如下所示:

        namespace Artech.WcfServices.Client.CalculatorServices
        {
            //其他類型成員
            [System.Diagnostics.DebuggerStepThroughAttribute()]
            [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel",
              "4.0.0.0")]
            public partial class CalculatorServiceClient : System.ServiceModel.
              ClientBase<Artech.WcfServices.Client.CalculatorServices.
              CalculatorService>, Artech.WcfServices.Client.CalculatorServices.
              CalculatorService {
              public CalculatorServiceClient() {
              }
              public CalculatorServiceClient(string endpointConfigurationName) :
                    base(endpointConfigurationName) {
              }
              public CalculatorServiceClient(string endpointConfigurationName,
                string remoteAddress) :
                    base(endpointConfigurationName, remoteAddress) {
              }
              public CalculatorServiceClient(string endpointConfigurationName,
                System.ServiceModel.EndpointAddress remoteAddress) :
                    base(endpointConfigurationName, remoteAddress) {
              }
              public CalculatorServiceClient(System.ServiceModel.Channels.Binding
                binding, System.ServiceModel.EndpointAddress remoteAddress) :
                    base(binding, remoteAddress) {
              }
              public double Add(double x, double y) {
                  return base.Channel.Add(x, y);
              }
              public double Subtract(double x, double y) {
                  return base.Channel.Subtract(x, y);
              }
              public double Multiply(double x, double y) {
                  return base.Channel.Multiply(x, y);
              }
              public double Divide(double x, double y) {
                  return base.Channel.Divide(x, y);
              }
        }

我們可以創(chuàng)建CalculatorServiceClient對象,執(zhí)行相應(yīng)方法調(diào)用服務(wù)操作。客戶端進(jìn)行服務(wù)調(diào)用的代碼如下:

        using System;
        using Artech.WcfServices.Client.CalculatorServices;
        namespace Artech.WcfServices.Client
        {
            class Program
            {
                static void Main(string[] args)
                {
                    using (CalculatorServiceClient proxy =
                      new CalculatorServiceClient())
                    {
                        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));
                    }
                }
            }
        }

運(yùn)行后輸出:

        x + y = 3 when x = 1 and y = 2
        x - y = -1 when x = 1 and y = 2
        x * y = 2 when x = 1 and y = 2
        x / y = 0.5 when x = 1 and y = 2

客戶端通過服務(wù)代理對象進(jìn)行服務(wù)的調(diào)用,上面的例子通過創(chuàng)建自動生成的、繼承自ClientBase<T>的類型對象進(jìn)行服務(wù)調(diào)用。實(shí)際上,我們還有另外一種創(chuàng)建服務(wù)代理的方法,就是通過ChannelFactory<T>。此外,WCF采用基于契約的服務(wù)調(diào)用方法,從上面的例子我們也可以看到,VS在進(jìn)行服務(wù)引用添加的過程中,會在客戶端創(chuàng)建一個與服務(wù)端等效的服務(wù)契約接口。在上面的例子中,由于服務(wù)端和客戶端都在同一個解決方案中,完全可以讓服務(wù)端和客戶端引用相同的契約。

為了演示這種場景,我們將添加的服務(wù)引用移除,并為Client項(xiàng)目添加對Contracts項(xiàng)目的引用。借助于這個服務(wù)契約,并通過ChannelFactory<ICalculator>創(chuàng)建服務(wù)代理對象,直接進(jìn)行相應(yīng)的服務(wù)調(diào)用。下面的代碼演示了基于ChannelFacotory<T>進(jìn)行服務(wù)代理的創(chuàng)建和服務(wù)調(diào)用的方式。

        using System;
        using System.ServiceModel;
        using Artech.WcfServices.Contracts;
        namespace Artech.WcfServices.Client
        {
            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));
                        }
                    }
                }
            }
        }

由于終結(jié)點(diǎn)是WCF進(jìn)行通信的唯一手段,ChannelFactory<T>本質(zhì)上是通過指定的終結(jié)點(diǎn)創(chuàng)建用于進(jìn)行服務(wù)調(diào)用的服務(wù)代理。在上面的代碼中,在創(chuàng)建ChannelFactory<T>的時候再在構(gòu)造函數(shù)中指定終結(jié)點(diǎn)的相關(guān)要素(契約通過泛型類型表示,地址和綁定則通過參數(shù)指定)。在真正的WCF應(yīng)用中,大都采用配置的方式進(jìn)行終結(jié)點(diǎn)的定義。我們可以通過下面的配置指定終結(jié)點(diǎn)的三要素,并為相應(yīng)的終結(jié)點(diǎn)指定一個終結(jié)點(diǎn)配置名稱(calculatorservice)。

        <?xml version="1.0" encoding="utf-8" ?>
        <configuration>
            <system.serviceModel>
                <client>
                    <endpoint address="http://127.0.0.1:9999/calculatorservice"
                      binding="wsHttpBinding" contract="Artech.WcfServices.Contracts.
                      ICalculator" name="calculatorservice" />
                </client>
            </system.serviceModel>
        </configuration>

那么在創(chuàng)建ChannelFactory<T>的時候,就無須再指定終結(jié)點(diǎn)的綁定和地址了,只須制定對應(yīng)的終結(jié)點(diǎn)配置名稱。

        using System;
        using System.ServiceModel;
        using Artech.WcfServices.Contracts;
        namespace Artech.WcfServices.Client
        {
            class Program
            {
                static void Main(string[] args)
                {
                    using (ChannelFactory<ICalculator> channelFactory =
                      new ChannelFactory<ICalculator>( "calculatorservice"))
                    {
                    //省略代碼
                    }
                }
            }
        }
主站蜘蛛池模板: 上虞市| 乾安县| 顺义区| 静海县| 西华县| 大邑县| 崇信县| 霞浦县| 沅江市| 中卫市| 顺昌县| 涟源市| 云龙县| 奉贤区| 栾川县| 禄劝| 绥江县| 永清县| 大埔区| 乌海市| 拜泉县| 永济市| 武强县| 隆德县| 晴隆县| 江门市| 泗阳县| 承德县| 通江县| 云浮市| 峡江县| 靖边县| 商丘市| 五大连池市| 新余市| 正蓝旗| 元谋县| 兖州市| 达拉特旗| 宜昌市| 临潭县|