在顾客端增多服务援用

图片 3

参考:

第四篇
初探通讯–ChannelFactory

 

透过前几篇的读书,大家大概驾驭了WCF的服务端-顾客端模型,可以创建叁个精短的WCF通讯程序,况兼能够把大家的劳务寄宿在IIS中了。我们禁不住咋舌WCF模型的轻便,寥寥数行代码和布局,就足以把通讯建构起来。然则,细心品尝一下,那其间依然有广大疑点:服务器是怎么着建起劳动的?我们在客商端调用贰个操作后发生了什么样?元数据到底是怎么着东西?等等。大家今后对WCF的理解应该还处在初级阶段,大家就能认为有数不尽这么的谜团了。

 

固然我们生活在WCF为大家营造的美好的应用层空间中,但是对于别的风姿罗曼蒂克项本事,大家都应力求做到知其所以然,对于底层知识的垂询有支持大家越来越好的领悟上层应用,由此在刚开首攻读入门的时候,慢一点、细一点,小编以为是很有受益的。

 

言归正传,大家几日前曾经知道了大器晚成件最基本的事体,顾客端和服务器是要拓宽通信的。那么这几个通讯是何等发生的吗?遵照大家日前的求学,从实操上看,我们在服务端定义好协定和达成,配置好公开的终结点,展开元数据沟通,在客户端增多服务引用,然后就径直new出来三个叫做XXXClient
的靶子,那么些指标具备服务协定里的有着办法,间接调用就足以了。细心思考?天哪,这一切是怎么发生的?!

 

服务端定义协定和落到实处并公然终结点,那看起来没什么难点,尽管我们对底层的完毕不打听,但终究是合乎逻辑的,而客户端怎么就经过贰个加上服务援用就化解一切了吧?就像秘密在这里个增添的劳务引用中。

 

展开第二篇中大家树立的顾客端(要是你为第三篇的IIS服务塑造了顾客端,张开那么些也行,作者用的正是其风流浪漫),看看服务援引里面有啥。

  1. 劳动援引初探

在设计方案浏览器中式点心击上方的”呈现全数文件”按键,然后实行服务援用。

图片 1

如此一大堆,有部分xsd文件大家恐怕明白是框架描述的文书档案,那wsdl什么的是怎么,还会有disco(迪斯科?)是怎么着,无所作为。

里面有一个cs文件,这么些可能大家应当看得懂,张开来看看

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

namespace HelloWcfClent.MyService {


    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName="MyService.IHelloWcfService")]
    public interface IHelloWcfService {

        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHelloWcfService/HelloWcf", ReplyAction="http://tempuri.org/IHelloWcfService/HelloWcfResponse")]
        string HelloWcf();

        [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IHelloWcfService/HelloWcf", ReplyAction="http://tempuri.org/IHelloWcfService/HelloWcfResponse")]
        System.Threading.Tasks.Task<string> HelloWcfAsync();
    }

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    public interface IHelloWcfServiceChannel : HelloWcfClent.MyService.IHelloWcfService, System.ServiceModel.IClientChannel {
    }

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
    public partial class HelloWcfServiceClient : System.ServiceModel.ClientBase<HelloWcfClent.MyService.IHelloWcfService>, HelloWcfClent.MyService.IHelloWcfService {

        public HelloWcfServiceClient() {
        }

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

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

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

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

        public string HelloWcf() {
            return base.Channel.HelloWcf();
        }

        public System.Threading.Tasks.Task<string> HelloWcfAsync() {
            return base.Channel.HelloWcfAsync();
        }
    }
}

诸有此类一群代码,都不是我们写的,起头看好似有多少个类/接口,IHelloWCF,那个应该是劳动协定,推测恐怕是从服务端下载来的,HelloWCFClient,那个便是我们的客商端代理嘛,大家在前头用过,原本是在那间定义的,但是后边世袭的ClientBase<>是干嘛用的,还重载了这样多的构造函数。还会有贰个IHelloWCFChannel接口,大家找遍应用方案也找不到哪个地区用到她了啊,干嘛在这里地定义出来啊?

先不去细想那么些代码的切实意思,看见此间,大家在对VS二〇〇八真挚赞扬的同时,不由得心中升起一丝忧虑,若无了VS贰零零玖,未有了IDE,未有了”增加服务援用”,大家该如何做?

就算咱们料想VS2009也不会毁灭,大家是足以一贯享受它提供给我们的便利的。然则大家前天在这里地商讨,无妨把调控等级向向下探底一个档期的顺序。看看上边有哪些。

 2. 大家自个儿写通讯

通讯到底是怎么发生的?轻松说正是四个终结点三个坦途,实际上客商端也可能有贰个终结点的,客商端会在这里七个终结点之间创设二个大路,然后把对服务端服务的调用封装成消息沿通道送出,服务器端获得新闻后在劳动器端建构劳动对象,然后实行操作,将重返值再封装成音信发给顾客端。

进程差不离是这么的,有个别地点大概不太严刻,然而这些逻辑咱们是足以知道的。如此看来,通信的劳作尤为重要部分都在顾客端这边,他要确立通道、发送音讯,服务端基本上在等待恳求。

顾客端要求哪些东西才具不负众望这一文山会海的操作呢?元数据和部分劳务的类。服务类由System.ServiceModel类库提供了,只差元数据。提到元数据大家禁不住倒吸一口凉气,难道是那一群XSD
OOXX的东西么?笔者以为,是亦不是。就大家那些事例来讲,元数据富含:服务协定、服务端终结点地址和绑定。对,就这么多。大家是还是不是迟早要因此元数据调换下载去服务端获取元数据吧,当然不是,就这几个事例来讲,服务端是大家规划的,这三地点的元数据大家本来是成竹于胸的。

 

由此,让服务引用见鬼去吗,我们自个儿来。

(1) 建构客商端。

以此历程我们很熟习,构建一个调节台应用程序,不做其余其余事,唯有清清爽爽的program.cs

 

(2) 增多供给的援引

最近说过,客户端完毕通讯的发起必要一些服务类的支撑,这么些类都定义在System.ServiceModel中,由此大家要丰富那个顺序集的援用。(注意是丰硕引用,不是劳务援用)。

图片 2

然后在Program.cs中using那一个命名空间

using System.ServiceModel;

(2)
编写服务协定

劳动协定是元数据中最要紧的有个别(还应该有数据协定等),协定接口是服务器和客商端一同持有的,客商端依靠协定来创建通道,然后在通道上调用协定的法子,方法的兑现,顾客端是不明了的。客商端只略知生机勃勃二方法签名和再次来到值(即接口)。

 

咱俩把在服务端定义的劳动协定纹丝不动的照搬过来,注意,只把接口搬过来,不要把得以达成也搬过来,那是服务端技术享有的。

 

劳务协定大家都很熟谙了,背着打出来吧。就写在Program类的背后

    [ServiceContract]  
    public interface IHelloWCF  
    {  
        [OperationContract]  
        string HelloWCF();  
    }  

OK,元数据的率先部分成功了,此外两某些大家在代码里面提供。

(3) 通道工厂登台

System.ServiceModel提供了八个名叫ChannelFactory<>的类,他接受劳务协定接口作为泛型参数,那样new出来的实例叫做服务协定XXX的大道工厂。看名就可以猜到其意义了,那几个工厂专门生产通道,这么些通道正是架设在服务器终结点和顾客端终结点之间的通讯通道了。由于那几个通道是用服务协定来树立的,所以就足以在这里个通道上调用那个服务协定的操作了。

其一通道工厂类的构造函数采纳部分重载参数,使用那个参数向通道工厂提供服务端终结点的音信,包蕴地点和绑定,那多亏元数据的别的两有个别。我们先把这两样做好策动着。

地点,也能够称终结点地址,实际上正是个U大切诺基I了,大家也许有一个专项使用的劳务类来表示她,叫做EndpointAddress,我们new多个它的实例:

EndpointAddress address = new EndpointAddress("http://localhost/IISService/HelloWCFService.svc"); 

只选用一个String参数,就是UOdysseyI地址,这里本人用了第三篇中树立的IIS服务之处。

绑定,大家的服务端终结点须要的是wsHttpBinding,大家也得以用服务类来表示,叫做WSHttpBinding,我们new一个它的实例:

WSHttpBinding binding =  WSHttpBinding();

 

采纳参数为空的构造函数就能够。

 

好的,元数据的其它分裂也策画齐全,现在请通道工厂闪亮上场,大家new三个它的实例,用刚刚树立的劳动协定接口作为泛型参数,使用方面创设的地点和绑定对象作为构造函数的参数:

ChannelFactory<IHelloWCF> factory =  ChannelFactory<IHelloWCF>(binding, address);  

有了工厂,接下去将在初叶临盆通道,通超过实际施通道工厂的CreateChannel方法来坐褥一个大路,由于工厂是用大家的签署接口创设的,所临蓐的坦途也是落到实处这一个接口的,大家得以向来用协定接口来声称其再次回到值。

 

IHelloWCF channel = factory.CreateChannel();  

 

于今,通道已经开发,大家得以调用这几个通道上的签署方法了。

string result = channel.HelloWCF();  

接下来大家把结果输出,犹如以前做的顾客端程序同样。

 Console.WriteLine(result);  
Console.ReadLine();  Console.WriteLine(result);  
Console.ReadLine(); 

图片 3

Yahoo!,大家向来不采取元数交流的功用,凭初步绘的元数据和代码就瓜熟蒂落了客商端到服务器端的通讯。未有服务引用、未有配备文件,大家依旧做获得。尽管对一切经过还不能够一心知晓,但是对通讯进程已经有一点点明白了。

 Program.cs的整个代码

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    using System.ServiceModel;  

    namespace ConsoleClient  
    {  
        class Program  
        {  
            static void Main(string[] args)  
            {  
                EndpointAddress address = new EndpointAddress("http://localhost/IISService/HelloWCFService.svc");  
                WSHttpBinding binding = new WSHttpBinding();  

                ChannelFactory<IHelloWCF> factory = new ChannelFactory<IHelloWCF>(binding, address);  

                IHelloWCF channel = factory.CreateChannel();  

                string result = channel.HelloWCF();  

                Console.WriteLine(result);  
                Console.ReadLine();  
            }  
        }  

        [ServiceContract]  
        public interface IHelloWCF  
        {  
            [OperationContract]  
            string HelloWCF();  
        }  
    }  
  1. 再展开一小点

到此处后生可畏度很成功了,大家再微微打开一些,还记得大家稍曾经在劳务援用生成的文书reference.cs看见的二个接口IHelloWCFChannel么?大家找遍解决方案也没觉察哪个地方接纳它?他是或不是没用的东西吗,当然不会,大家以后来研究一下它。

 

我们地点手绘的前后相继能够展开通道并调用服务,不过大家回看我们事先经过劳动引用创设的顾客端都以提供二个Close()方法来关闭服务连接的。使用大家这种艺术按说也应有关闭通道才对,纵然顾客端关闭通道就能被关闭了,然则在动用完通道后关门之连接好的习于旧贯。

 

只是,怎么着达成啊?大家开采通道不能提供关闭的章程,那是因为大家用IHelloWCF接口注脚的通道对象,那这几个目的自然只可以提供接口所分明的不二秘诀了。而其实通道对象自己是提供关闭措施,只是被大家浮现的接口评释给挡住了,通道其实早已完毕了另二个接口叫做IClientChannel,这一个接口提供了开辟和倒闭通道的办法。假设大家要调用,只供给把通道对象强制调换到IClientChannel接口类型就能够了:

 不过,怎样促成吗?我们开掘通道不可能提供关闭的点子,那是因为大家用IHelloWCF接口申明的大道对象,那这几个指标自然只可以提供接口所分明的章程了。而实在通道对象自笔者是提供关闭措施,只是被大家来得的接口注明给挡住了,通道其实已经完成了另一个接口叫做IClientChannel,那么些接口提供了张开和关闭通道的情势。假诺大家要调用,只供给把通道对象强制转变到IClientChannel接口类型就足以了:

((IClientChannel)channel).Close(); 

然则这么做远远不足自然文雅,强制转变总是令人莫名苦闷的东西。能或无法保持IHelloWCF的对象类型并让她得以提供关闭措施呢?当然是足以的。大家再建构三个接口,让那么些接口同一时间贯彻IHelloWCF服务协定接口和IClientChannel接口,并用那些新接口去new
通道工厂,那样坐蓐出来的大路对象不就足以同期利用IHelloWCF中的服务操作和IClientChannel中的关闭通道的措施了么?

 

 

率先,做那么些新接口,那几个接口只是把劳务协定接口和IClientChannel拼接,本身未有别的成员,是三个空中接力口。

 

 

 public interface IHelloWCFChannel : IHelloWCF, IClientChannel  
{   

}

接下来,改善一下前面的确立通道工厂的语句,用这几个新接口名作为泛型参数来new通道工厂

ChannelFactory<IHelloWCFChannel> factory = new ChannelFactory<IHelloWCFChannel>(binding, address);

改革一下生育通道方法的指标注解类型,用新接口类型表明:

IHelloWCFChannel channel = factory.CreateChannel();  

末段,大家在调用服务操作之后,就足以一向调用关闭通道的不二等秘书技了:

channel.Close();  

订正后的program.cs源代码:

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    using System.ServiceModel;  

    namespace ConsoleClient  
    {  
        class Program  
        {  
            static void Main(string[] args)  
            {  
                EndpointAddress address = new EndpointAddress("http://localhost/IISService/HelloWCFService.svc");  
                WSHttpBinding binding = new WSHttpBinding();  

                ChannelFactory<IHelloWCFChannel> factory = new ChannelFactory<IHelloWCFChannel>(binding, address);  

                IHelloWCFChannel channel = factory.CreateChannel();  

                string result = channel.HelloWCF();  

                channel.Close();  

                Console.WriteLine(result);  
                Console.ReadLine();  
            }  
        }  

        [ServiceContract]  
        public interface IHelloWCF  
        {  
            [OperationContract]  
            string HelloWCF();  
        }  

        public interface IHelloWCFChannel : IHelloWCF, IClientChannel  
        {   

        }  

    }  

最近,大家明白了劳务援用中非常看上去没用的接口是何等效果了啊。可是服务引用中的达成跟大家这种依然有分别的,它应用了二个称呼ClientBase<>的类来开展通道通讯,大家前边会开展。

  1. 总结

明日的商讨稍稍尖锐了一丝丝,未有完全领悟也尚无涉嫌,心里有个概念就足以了。

我们经过手绘代码的主意达成了顾客端和服务端的通讯,未有依赖元数据调换工具。那让我们对服务端和顾客端通信有了更近乎真相的后生可畏层认知。其实所谓的元数据沟通正是让大家得到这么以至更简短的编制程序模型,它背后做的政工跟大家今日做的是很周围的,想像一下,成品级的服务只怕有为数不菲的签定接口,超级多的终结点,大家不容许也不该花费劲气把他们在客商端中再手动提供壹回,由此元数据调换是很有含义的,大家相应学会使用它,大家还要在末端的求学中连连左右明白元数据交流工具的秘技。