吉吉于

free

WCF笔记2:创建客户端调用服务

1.通过为Client添加服务引用,右键点击Client项目,在弹出的上下文中选择”添加服务引用”,在地址栏中填写服务元数据的发布源地址

VS会自动生成一系列的用于服务调用的代码和配置。

在一系列自动生成的类中,包含一个服务契约借口,一个服务代理对象和其他相关的类。

被客户端直接用于服务调用的是一个继承自ClientBase〈CalculatorService〉并实现了CalculatorService接口的服务代理类。

app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_CalculatorService" />
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding"
                bindingConfiguration="WSHttpBinding_CalculatorService" contract="ServiceReference1.CalculatorService"
                name="WSHttpBinding_CalculatorService">
                <identity>
                    <userPrincipalName value="Flowerowel-PC\Flowerowel" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

ClientBase〈CalculatorService〉的定义如下所示:

//------------------------------------------------------------------------------
// <auto-generated>
//     此代码由工具生成。
//     运行时版本:4.0.30319.17626
//
//     对此文件的更改可能会导致不正确的行为,并且如果
//     重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------

namespace Client.ServiceReference1 {

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(Namespace="Lazynight", ConfigurationName="ServiceReference1.CalculatorService")]
    public interface CalculatorService {

        [System.ServiceModel.OperationContractAttribute(Action="Lazynight/CalculatorService/Add", ReplyAction="Lazynight/CalculatorService/AddResponse")]
        double Add(double x, double y);

        [System.ServiceModel.OperationContractAttribute(Action="Lazynight/CalculatorService/Subtract", ReplyAction="Lazynight/CalculatorService/SubtractResponse")]
        double Subtract(double x, double y);

        [System.ServiceModel.OperationContractAttribute(Action="Lazynight/CalculatorService/Multiply", ReplyAction="Lazynight/CalculatorService/MultiplyResponse")]
        double Multiply(double x, double y);

        [System.ServiceModel.OperationContractAttribute(Action="Lazynight/CalculatorService/Divide", ReplyAction="Lazynight/CalculatorService/DivideResponse")]
        double Divide(double x, double y);
    }

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    public interface CalculatorServiceChannel : Client.ServiceReference1.CalculatorService, System.ServiceModel.IClientChannel {
    }

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    public partial class CalculatorServiceClient : System.ServiceModel.ClientBase<Client.ServiceReference1.CalculatorService>, Client.ServiceReference1.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);
        }
    }
}

接下来就可以创建CalculatorServiceClient对象,执行相应的方法调用服务操作,客户端进行服务调用的代码入下:

using (CalculatorServiceClient proxy = new CalculatorServiceClient())
            {
                System.Console.WriteLine("x+y={2}when x={0} and y={1}",1,2,proxy.Add(1,2));
            }

 2. 通过ChannelFactory

在上面的例子可以看到客户端会创建一个与服务端等效的服务契约接口。我们可以让服务端和客户端引用相同的契约。

现在讲刚才添加的服务引用删除,并为Client项目添加对Contracts项目的引用,借助于这个服务契约,并通过ChannelFactory创建服务代理对象,直接进行相应的服务调用。

下面的代码掩饰了基于ChannelFactory进行服务代理的创建和服务调用的方式。

using System;
using System.ServiceModel;
using Contracts;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ChannelFactory<ICaculator> ChannelFactory = new ChannelFactory<ICaculator>(new WSHttpBinding(), "http://127.0.0.1:9999/calculatorservice"))
            {
                ICaculator 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}",2,1,proxy.Subtract(2,1));
                }
            }
        }
    }
}

3.简化第二种方法

由于终结点是WCF进行通信的唯一手段,ChannelFactory本质上是通过制定的终结点创建用于进行服务调用的服务代理。

在上面的代码中,在创建ChannelFactory的时候再在构造函数中制定终结点的相关要素(契约通过泛型类表示,地址和绑定则通过参数制定)。

在真正的WCF应用中,大都采用配置的方式进行终结点的定义。我们可以通过下面的配置制定终结点的三要素,并为相应的终结点制定一个终结点配置名称(calculatorservice)。

那么在创建ChannelFactory的时候,就无需再制定终结点的绑定和地址了,只需制定对应的终结点配置名称。

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

 

using System;
using System.ServiceModel;
using Contracts;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ChannelFactory<ICaculator> channelfactory = new ChannelFactory<ICaculator>("calculatorservice"))
            {
                ICaculator proxy=channelfactory.CreateChannel();
                using (proxy as IDisposable)
                {
                    Console.WriteLine("x+y={2} when x={0} and y={1}",1,2,proxy.Add(1,2));
                }

            }
        }
    }
}

 

 

转载请注明:于哲的博客 » WCF笔记2:创建客户端调用服务