绛河 初识WCF4

参考:

第四篇
初探通讯–ChannelFactory

 

透过前几篇的就学,大家大致明白了WCF的服务端-顾客端模型,能够建构二个轻易的WCF通讯程序,而且能够把大家的劳务寄宿在IIS中了。大家禁不住惊讶WCF模型的简易,寥寥数行代码和布局,就能够把通讯建立起来。然则,留神品尝一下,这里面依然有为数不菲难题:服务器是何许建起服务的?我们在客商端调用二个操作后发出了哪些?元数据到底是如陈家福西?等等。大家前些天对WCF的精通应该还地处初级阶段,大家就能够以为有众多那样的谜团了。

 

就算咱们生活在WCF为大家创设的美好的应用层空间中,不过对于别的生龙活虎项技能,大家都应力求幸不辱命知其所以然,对于底层知识的问询有扶植我们越来越好的精通上层应用,由此在刚早前攻读入门的时候,慢一点、细一点,作者以为是大有裨益的。

 

闲话少说,大家未来早已知道了意气风发件最宗旨的事务,客户端和服务器是要扩充通讯的。那么那个通讯是如何爆发的啊?依据大家近些日子的读书,从实操上看,大家在服务端定义好协定和贯彻,配置好公开的终结点,张开元数据沟通,在顾客端加多服务援用,然后就径直new出来二个叫做XXXClient
的靶子,那个指标具有服务协定里的有着办法,直接调用就足以了。留神揣摩?天哪,那整个是怎么爆发的?!

 

服务端定义协定和促成并公开终结点,那看起来没什么难点,就算大家对底层的贯彻不通晓,但毕竟是合乎逻辑的,而客商端怎么就经过三个抬高服务援用就消除一切了吧?就如秘密在此个增加的服务援用中。

 

开荒第二篇中我们创造的客商端(假诺你为第三篇的IIS服务创建了顾客端,展开那些也行,笔者用的正是这么些),看看服务援引里面有哪些。

  1. 劳动援引初探

在施工方案浏览器中式点心击上方的”展现全数文件”开关,然后开展服务引用。

www.350.vip 1

www.350.vip ,这般一大堆,有点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中,因而大家要增加那些顺序集的引用。(注意是加上援引,不是劳务引用)。

www.350.vip 2

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

using System.ServiceModel;

(2)
编写服务协定

劳动协定是元数据中最要害的有的(还有数据协定等),协定接口是服务器和客商端一同具备的,客户端依靠协定来创立通道,然后在通路上调用协定的章程,方法的贯彻,顾客端是不精晓的。客商端只精通方法签字和再次回到值(即接口)。

 

大家把在服务端定义的劳动协定纹丝不动的照搬过来,注意,只把接口搬过来,不要把贯彻也搬过来,那是服务端能力抱有的。

 

劳务协定大家都很了解了,背着打出去啊。就写在Program类的前边

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

OK,元数据的率先片段形成了,别的两部分大家在代码里面提供。

(3) 通道工厂进场

System.ServiceModel提供了多少个名字为ChannelFactory<>的类,他收受劳务协定接口作为泛型参数,这样new出来的实例叫做服务协定XXX的通道工厂。看名称就能够想到其意义了,这么些工厂特意生产通道,那个通道便是架设在服务器终结点和客商端终结点之间的通信通道了。由于那么些通道是用服务协定来确立的,所以就能够在这里个通道上调用那个服务协定的操作了。

这些通道工厂类的构造函数选用一些重载参数,使用这几个参数向通道工厂提供服务端终结点的音信,包蕴地点和绑定,那正是元数据的别的两局地。大家先把这两样做好希图着。

地点,也足以称终结点地址,实际上就是个UOdysseyI了,我们也是有一个专项使用的劳动类来代表他,叫做EndpointAddress,大家new贰个它的实例:

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

只选择一个String参数,正是UPAJEROI地址,这里自个儿用了第三篇中创设的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(); 

www.350.vip 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. 总结

几天前的钻研微微尖锐了一丝丝,没有完全知晓也从不关系,心里有个概念就能够了。

大家通过手绘代码的情势完结了客户端和服务端的通讯,没有依据元数据调换工具。那让大家对服务端和客户端通讯有了更相仿真相的后生可畏层认知。其实所谓的元数据调换就是让咱们获得这么以至更简约的编制程序模型,它背后做的事体跟大家后天做的是很周围的,想像一下,产级其他服务只怕有许多的缔约接口,大多的终结点,我们不恐怕也不该开销劲气把他们在顾客端中再手动提供二回,由此元数据沟通是很有意义的,我们应有学会运用它,大家还要在前边的学习中不断左右驾驭元数据调换工具的办法。

 

发表评论

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