服务端定义协定和贯彻并当面终结点

参考:

第四篇
初探通讯–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接口,大家找遍消除方案也找不到如哪个地方方用到她了呀,干嘛在这里定义出来呢?

先不去细想那个代码的求实意思,看到这里,我们在对VS2009真挚称赞的还要,不由得心中升起一丝心焦,若无了VS二零零六,未有了IDE,未有了”加多服务援引”,我们该如何做?

尽管大家料想VS二〇〇九也不会消失殆尽,我们是足以一直享受它提要求大家的福利的。可是我们前几日在此间商讨,不要紧把调节等第向向下探底一个档期的顺序。看看上边有怎么着。

 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的大路工厂。顾名思义了,这一个工厂专门生产通道,这几个通道就是架设在服务器终结点和客户端终结点之间的通讯通道了。由于这些通道是用服务协定来确立的,所以就能够在那么些通道上调用这些服务协定的操作了。

服务端定义协定和贯彻并当面终结点。那一个通道工厂类的构造函数接受一些重载参数,使用那几个参数向通道工厂提供服务端终结点的新闻,蕴涵地方和绑定,那便是元数据的任何两局地。大家先把这两样做好准备着。

服务端定义协定和贯彻并当面终结点。地址,也得以称终结点地址,实际上正是个UCRUISERI了,大家也可以有贰个专项使用的劳务类来表示她,叫做EndpointAddress,大家new三个它的实例:

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

只接受一个String参数,正是U奥德赛I地址,这里作者用了第三篇中确立的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. 总结

前些天的斟酌稍微尖锐了一丢丢,未有完全明了也尚无涉嫌,心里有个概念就能够了。

我们透过手绘代码的法门完结了客户端和服务端的通讯,未有借助元数据沟通工具。那让大家对服务端和客户端通讯有了更近乎真相的一层认知。其实所谓的元数据沟通就是让我们得到如此甚至更简短的编制程序模型,它背后做的事务跟我们后天做的是很临近的,想像一下,产等第的服务大概有成都百货上千的签订接口,多数的终结点,我们不容许也不该开销劲气把他们在客户端中再手动提供贰次,由此元数据沟通是很有意义的,大家理应学会使用它,大家还要在背后的就学中不停左右精通元数据沟通工具的章程。

 

You may also like...

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图