WCF编程系列(七)信道及信道工厂

 

信道及信道栈

前面已经提及过,WCF中客户端与服务端的交互都是通过消息来进行的。消息从客户端传送到服务端会经过多个处理动作,在WCF编程模型中,这些动作是按层 次进行的:上一层次对消息处理完成后,将消息传递给下一层次,依次类推。这里对应的每个层即为信道(我们可以理解为消息通道)。而这一些列的信道层构成了 一个信道栈。明显的,信道栈中的最后一个信道应该是传输信道,该信道将处理后的消息发送给服务端或接受从服务端返回的消息应答,而在传输信道之上还有一系 列的协议信道,这些信道将对消息进行加工处理。

我们可以把信道看做是绑定的实现,从前面示例可以看出,绑定实际上是一个终结点的配置,这个配置影响到客户端与服务端交互时消息的传输及处理方式(使用何 种协议进行传输、消息的编码方式、消息遵循的安全协议等待)。绑定本身是有一系列的绑定元素组合而成的,每个绑定元素必然会有一个信道层与之对应,最终绑 定元素通过对应的信道层对消息产生影响。

信道工厂

信道堆栈通常是使用工厂模式创建的,在这种模式中,绑定创建信道堆栈。 在客户端,使用绑定生成信道工厂ChannelFactory,然后ChannelFactory生成信道堆栈并返回对堆栈中顶部信道的引用。 之后,应用程序可以使用此信道发送消息。

在服务端,使用绑定生成信道侦听器 IChannelListener,用于侦听传入消息。 IChannelListener 通过创建信道堆栈并将应用程序引用传递给顶部信道,将消息提供给侦听应用程序。 之后,应用程序使用此信道接收传入消息。(注意:关于服务端使用的信道侦听器将在后面介绍,本文只讲述客户端使用的信道工厂)

OK,总结一下:

1.绑定有一些列的绑定元素组成,每个绑定元素对应一个信道

2.信道负责对消息的加工处理

3.信道按绑定元素在绑定中的堆叠顺序组成信道栈

4.信道由信道工厂生成,而信道工厂由绑定来创建(绑定调用每个绑定元素的信道工厂创建信道,并返回信道栈中的首个信道)

ChannelFactory<T>泛型类

信道工厂类是一个泛型类,用以创建信道。参数类型T通常是我们的服务契约接口(IFirstService),这样既可实现信道与服务契约的关联。

信道工厂有7个公共的构造函数,构造函数的参数最终是为了构建一个服务终结点(ServiceEndPoint),如果使用无参数的构造函数,则实例化后可以通过EndPoint属性来设置终结点的属性。关于具体函数声明,请参见MSDN。

信道工厂另一个重要的方法是创建信道:CreateChannel,此方法返回一个T类型实例,即服务契约接口的实例。所以通过这个实例,在客户端我们可以像操作本地对象一样,直接调用服务方法。

在示例一中,我们是使用的svcutil生成的客户端代码,在生成的代码文件中,定义了一个服务契约接口IFirstService,当然这个接口是必须 的。而另一个类为FirstServiceClient,它继承与ClientBase<IFirstService>及 IFirstService,在此类中封装了对信道工厂的操作,我们通常把此类称作客户端代理类,注意类中IFirstService接口方法的实现代 码:

隐藏行号 复制代码 ? GetData
  1. public string GetData(string name)
  2. {
  3.     return base.Channel.GetData(name);
  4. }

直接调用了基类(ClientBase<IFirstService>中Channel的GetData方法,Channel属性实际上就是 通过ChannelFactory<IFirstService>信道工厂的CreateChannel方法返回的一个 IFirstService实例。所有,FirstServiceClient类只是为了封装信道工厂的基本操作,svcutil通过生成此类,是我们在 客户端应用程序中无需直接操作信道工厂,而直接调用服务,回忆我们客户端Program.cs中的调用代码:

隐藏行号 复制代码 ? Program.cs
  1. FirstServiceClient client = new FirstServiceClient("BasicHttpBinding_IFirstService");
  2.                Console.WriteLine("使用BASIC HTTP绑定:" + client.GetData(key));

关于ClientBase<IFirstService>类是WCF为客户端提供的一个基类,其中实现了对信道工厂的操作。不过此类只能用作 基类并且不可实例化,所以客户端代理类通过继承ClientBase<IFirstService>的方式,实现了对信道的基本操作。了解客 户端代理类,服务契约接口及ClientBase类的关系后,我们完全可以自己实现客户端代理类:从ClientBase派生,并通过 ClientBase中的Channel对应的服务契约方法来实现客户端代理类的服务契约接口(GetData方法的实现)。

当然,通过客户端代理类方法是一种标准的客户端实现方式,但是我们也可以通过直接操作信道工厂来实现客户端调用代码,其实很简单:

隐藏行号 复制代码 ? Program.cs
  1. ChannelFactory<IFirstService> cf = new ChannelFactory<IFirstService>(new BasicHttpBinding(), "http://localhost:8000/");
  2. IFirstService s = cf.CreateChannel();
  3. Console.WriteLine(s.GetData(key));

WCF编程系列(七)信道及信道工厂的更多相关文章

  1. WCF编程系列(六)以编程方式配置终结点

    WCF编程系列(六)以编程方式配置终结点   示例一中我们的宿主程序非常简单:只是简单的实例化了一个ServiceHost对象,然后调用open方法来启动服务.而关于终结点的配置我们都是通过配置文件来 ...

  2. WCF编程系列(四)配置文件

    WCF编程系列(四)配置文件   .NET应用程序的配置文件 前述示例中Host项目中的App.config以及Client项目中的App.config称为应用程序配置文件,通过该文件配置可控制程序的 ...

  3. WCF编程系列(五)元数据

    WCF编程系列(五)元数据   示例一中我们使用了scvutil命令自动生成了服务的客户端代理类: svcutil http://localhost:8000/?wsdl /o:FirstServic ...

  4. WCF编程系列(二)了解WCF

    WCF编程系列(二)了解WCF   面向服务     服务是复用进化的结果,起初的复用是函数,面向对象编程的出现使复用从函数上升到对象,随后面向组件编程又将复用从对象上升到组件,现在面向服务编程将复用 ...

  5. WCF编程系列(三)地址与绑定

    WCF编程系列(三)地址与绑定   地址     地址指定了接收消息的位置,WCF中地址以统一资源标识符(URI)的形式指定.URI由通讯协议和位置路径两部分组成,如示例一中的: http://loc ...

  6. WCF编程系列(一)初识WCF

    WCF编程系列(一)初识WCF   Windows Communication Foundation(WCF)是微软为构建面向服务的应用程序所提供的统一编程模型.WCF的基本概念:  地址:定义服务的 ...

  7. 学习ASP.NET Core Razor 编程系列七——修改列表页面

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  8. java并发编程系列七:volatile和sinchronized底层实现原理

    一.线程安全 1.  怎样让多线程下的类安全起来 无状态.加锁.让类不可变.栈封闭.安全的发布对象 2. 死锁 2.1 死锁概念及解决死锁的原则 一定发生在多个线程争夺多个资源里的情况下,发生的原因是 ...

  9. MapReduce 编程 系列七 MapReduce程序日志查看

    首先,假设须要打印日志,不须要用log4j这些东西,直接用System.out.println就可以,这些输出到stdout的日志信息能够在jobtracker网站终于找到. 其次,假设在main函数 ...

随机推荐

  1. PowerDesigner实用技巧小结(4)

    下述十四个技巧,是许多人在大量的数据库分析与设计实践中,逐步总结出来的.对于这些经验的运用,读者不能生帮硬套,死记硬背,而要消化理解,实事求是,灵活掌握.并逐步做到:在应用中发展,在发展中应用. 1. ...

  2. 编写一个Java应用程序,该程序包括3个类:Monkey类、People类和主类 E。要求: (1) Monkey类中有个构造方法:Monkey (String s),并且有个public void speak() 方法,在speak方法中输出“咿咿呀呀......”的信息。 (2)People类是Monkey类的子类,在People类中重写方法speak(),在speak方法 中输出“小样的,不

    package homework1; public class Monkey { //构造方法 Monkey(String s) { } //成员方法 public void speak() { Sy ...

  3. 在ubuntu上面配置nginx实现反向代理

    1.下载nginx    官网:http://nginx.org/en/download.html    直接在服务器上下载 wget http://nginx.org/download/nginx- ...

  4. ios基础知识

    1获取系统语言设置 NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; NSArray *languages = ...

  5. BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 LCT

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOn ...

  6. hdu 5432 Pyramid Split 二分

    Pyramid Split Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://bestcoder.hdu.edu.cn/contests/conte ...

  7. kettle參数、变量具体解说

    kettle參数.变量具体解说 kettle 3.2 曾经的版本号里仅仅有 variable 和 argument,kettle 3.2 中.又引入了 parameter 概念.variable 即e ...

  8. android报错及解决1--Bitmap加载时,报bitmap size exceeds VM budget

    报错描述: 用Bitmap加载图片资源时,报错java.lang.OutOfMemoryError: bitmap size exceeds VM budget 原因分析: android系统限制,只 ...

  9. [Effective C++ --023]宁以non-member、non-friend替换member函数

    作者在这一节中花了大幅度的篇幅来介绍为什么最好使用non-member.non-friend函数. 思路如下: 场景:如果有一个class用来表示网页浏览器,那么清楚缓存及历史记录的时候,我们可能定义 ...

  10. windows下ftp上传下载和一些常用命令

    先假设一个ftp地址 用户名 密码 FTP Server: home4u.at.china.com User: yepanghuang Password: abc123 打开windows的开始菜单, ...