「服务」WCF客户端调用方式Channel/Client

WCF通信的几个必要信息就是:地址、终结点、协议。

本文整理一下客户端的调用方法(通过使用函数的形式)

我目前只使用过几种binding类型,不同的Binding类型,其客户端的调用方式可能也会有些许区别,所以,一下内容仅作参考。

1、使用Channel的形式

也就是用ChannelFactory。

参考上一篇「服务」WCF中NetNamedPipeBinding的应用实例 客户端的调用方式;

1、需要服务协议内容,也就是把服务端,接口(文件)复制过来,添加到项目中,

比如,服务端的【IServer1.cs】:

//服务端的接口文件!!!
using System.ServiceModel;
//注意命名空间
namespace ConsolePipeWcf1.Server1
{
    [ServiceContract]
    interface IServer1
    {
        [OperationContract]
        string GetData(int value);
    }
}

在客户端,应用这个命名空间、并添加【System.ServiceModel】引用,接着就可以通过如下代码进行调用:

//客户端调用
using System;
//!!
using System.ServiceModel;
using ConsolePipeWcf1.Server1;//step1: Contract
 
namespace ConsoleServer1Client
{
    class Program
    {
        static void Main(string[] args)
        {
            //step2: Binding
            var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.Transport);
            //step3: Address
            var address = new EndpointAddress("net.pipe://localhost/console/server1/");
            //-------------------------------  ↓(1)---- ↓(2)--- ↓(3)---
            var factory = new ChannelFactory<IServer1>(binding, address);
            IServer1 channel = factory.CreateChannel();
            string s = channel.GetData(5);//随便给个数
            Console.WriteLine(s);
            Console.ReadKey();
        }
    }
}

2、使用Client的形式

2.1、添加服务引用的方式

很多教程的方法是在客户端中,直接添加“服务引用”,然后写代码。这种方式更加方便,先来说一下这种方式的操作步骤:

1、首先要把服务端启动起来,启动起来。

2、在客户端的程序上,右键项目名,选择【添加】->【服务引用】

接着把服务地址,确切的讲是mex地址(如果没有单独设置mex地址的话,默认的是在基地址后面添加“/mex”),填进去。

点击【转到】,会检测到现有的服务,如下图:

可以修改下命名控件,然后点击【确定】,即添加服务引用成功。

然后使用如下代码进行调用:

//客户端调用
using System;
//!!
using System.ServiceModel;
 
namespace ConsoleServer1Client
{
    class Program
    {
        static void Main(string[] args)
        {
            //添加服务引用的命名空间
            ServiceReference1.Server1Client client = new ServiceReference1.Server1Client();
            string str = client.GetData(9);
            Console.WriteLine(str);
            Console.ReadKey();
        }
    }
}

2.2、纯手工的方式

如果我在写服务端、别人在写客户端,或者反过来,但在开发阶段,通过添加【服务应用】的方式并不方便,或者添加完后,最终代码整合、迁移,搞得不能用了怎么办?

仔细看了下添加【服务应用】后,在代码种XXXClient(例如上面代码种的Server1Client)的定义,发现其实只是VS自动生成了一部分代码,这部分代码分两部分(或者说三部分):一是服务端的接口,二是对接口进行封装,创建客户端类,(三是一些地址、绑定类型的配置文件),这些文件在客户端代码根目录下的【Connected Services】文件夹下。

把自动生成的【ServiceReference1.cs】文件种的Client类主体分割出来,如下:

class Server1Client: System.ServiceModel.ClientBase<NS.IServer1>,NS.IServer1
{

    public Server1Client()
    {
    }

    public Server1Client(string endpointConfigurationName) :
            base(endpointConfigurationName)
    {
    }

    public Server1Client(string endpointConfigurationName, string remoteAddress) :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public Server1Client(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public Server1Client(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
            base(binding, remoteAddress)
    {
    }

    public string GetData(int value)
    {
        return base.Channel.GetData(value);
    }

}

类似于前面介绍的channel方法,在有了接口文件之后,再用上面的代码创建一个Server1Client类即可(类名可以随便起,注意命名空间写对),效果是一样的。

比如我复制上面的代码,然后删除【服务引用】,把服务端的【IServer1.cs】文件复制过来,然后利用上面复制的代码,写一个新类:

//引用复制过来的IServer1的命名空间
using ConsolePipeWcf1.Server1;

//客户端命名空间下的
namespace WCFNetNamedClientDemo
{
    class MyNewClient : System.ServiceModel.ClientBase<IServer1>, IServer1
    {
        //无参构造函数 需要搭配【App.Config】文件使用
        public MyNewClient(){}

        public MyNewClient(string endpointConfigurationName) :
                base(endpointConfigurationName)
        {}
        public MyNewClient(string endpointConfigurationName, string remoteAddress) :
                base(endpointConfigurationName, remoteAddress)
        {}
        public MyNewClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
                base(endpointConfigurationName, remoteAddress)
        {}
        //通过代码的方式 指定Binding和Address
        public MyNewClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
                base(binding, remoteAddress)
        {}

        public string GetData(int value)
        {
            return base.Channel.GetData(value);
        }

    }
}

换句话说,如果我开发服务端,我只需要把接口文件,以及这个MyNewClient 类文件,提供给客户端一样可以实现调用。

区别的一点是,通过VS添加服务应用,会自动配置地址和绑定类型。

如果用纯手工的方式,就需要在代码种指定一下Address和Binding了,例如:

//声明是什么Binding
NetNamedPipeBinding binding = new NetNamedPipeBinding();
//申明地址
EndpointAddress address = new EndpointAddress("net.pipe://localhost/console/server1/");
//使用对应参数的构造函数
MyNewClient client = new MyNewClient(binding, address);
string str = client.GetData(9);
Console.WriteLine(str);

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值