WCF后传系列(8):深度通道编程模型Part 1—设计篇

引言

从本质上说,WCF是一个通信服务框架,它允许我们使用不同的传输协议,使用不同的消息编码形式,跟不同的WS-*系列规范交互,而所有这些细节都是由通道堆栈来处理的。为了简化这些处理,在WCF中提供了两种模型,一是针对开发者的应用程序编程模型;二是用来通信的通道模型,这样对于开发者来说,只要了解应用程序编程模型就足够了,而不会涉及到通道模型,然而,对于通道模型进行必要的学习,可以让我们真正理解WCF中“通信”概念,了解WCF的 整个架构体系,从而构建出更加健壮的WCF服务或者对WCF框架进行扩展。在本文中,我们将进行深度了解WCF中的通道模型是如何设计的。

通道模型概述

在WCF中,提供了一系列的接口和其它类型模型,它们为消息的发送和接收提供了一个底层的编程模型,该模型称之为WCF通道模型。在通道模型中,一个很重要的概念是通道堆栈,它是具有一个或多个消息处理通道的分层的通信堆栈,堆栈中放置了各种类型的通道,用来对象进行处理,如在通道堆栈的最底层放置了传输通道,它负责使通道堆栈适应基础传输,如图1所示:

TerryLee_WCF_23

图1

在通道堆栈中,不仅仅提供消息的传输方式,还提供了其它诸如对消息的内容或者消息头进行处理的功能,这些功能同样是以通道的方式放置在通道堆栈中,甚至于我们可以编写自己的通道,加入到通道堆栈中。

消息在通道堆栈中传输时,将作为Message对象流过通信堆栈,如传输通道负责在发送方和接收方之间转换消息,之后消息将通过传输通道继续往上流,依次经过通道堆栈中的各个通道,这些通道各自负责提供一种通信功能,如在消息头中添加信息,对消息的正文进行加密等等。

通道对象模型

通道对象模型是实现通道、通道侦听器和通道工厂所必需的一组核心接口。还提供一些基类以辅助自定义实现。可以看到通道模型中最重要的有三组接口:通道、通道侦听器和通道工厂。每个通道均实现一个或多个接口,称为通道形状接口或通道形状;通道侦听器负责侦听传入消息,即在消息的接收端,然后通过由通道侦听器创建的通道将这些消息传送到上面的层;通道工厂负责创建通道用于发送消息,即在消息的发送方,并在通道工厂关闭时,关闭通道工厂创建的所有通道。

在通道模型中,最重要的一个接口是ICommunicationObject,它定义了所有通信对象实现的基本状态机的核心接口,自定义通道通信对象可以直接实现ICommunicationObject,如图2所示:

TerryLee_WCF_24

图2

只有图2中的这些接口,才属于WCF的通道模型,在WCF中同样提供了一些基类如CommunicationObject、ChannelFactoryBase等,在实现自定义的通道通信对象时,也可以直接继承于这些基类,但要注意,这些基类仅仅是为实现自定义通道通信对象提供了方便,它们本身并不属于通道模型的一部分。

ICommunicationObject接口为WCF中所有面向通信的对象提供了契约,除了通道、通道侦听器、通道工厂外,还有调度程序和服务主机,定义了基本状态的协定。它包括一组用于启动状态转换的打开、关闭和中止方法,打开和关闭方法的异步版本,一组提供状态转换通知的事件和一个个用于检查对象状态的公开State属性,它的定义如下所示:

public interface ICommunicationObject
{
    // 状态属性
    CommunicationState State { get; }

    // 事件
    event EventHandler Closed;
    event EventHandler Closing;
    event EventHandler Faulted;
    event EventHandler Opened;
    event EventHandler Opening;

    // 方法
    void Abort();
    void Close();
    void Close(TimeSpan timeout);
    void Open();
    void Open(TimeSpan timeout);

    // 异步方法
    IAsyncResult BeginClose(AsyncCallback callback, object state);
    IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state);
    IAsyncResult BeginOpen(AsyncCallback callback, object state);
    IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state);
    void EndClose(IAsyncResult result);
    void EndOpen(IAsyncResult result);
}

ICommunicationObject 的初始状态是“已创建”,此时可以配置它的各种属性。 一旦处于“已打开”状态,对象就可用于发送和接收消息,但它的属性将视为不可变。 一旦处在“正在关闭”状态,对象就不能再处理新的发送或接收请求,但在到达“关闭”超时前有可能完成现有的请求。 如果发生不可恢复的错误,则对象将转换到“出错”状态,此时可以检查该对象以获取有关错误的信息,该对象最终将关闭。 处于“已关闭”状态时,该对象实质上已到达状态机的终点。 对象一旦从一个状态转换到下一个状态,它将不会返回至前一状态,整个过程图3所示:

TerryLee_WCF_30

图 3

通道形状

每个通道均实现一个或多个接口,称为通道形状接口或通道形状。通道形状的最底层是 IChannel 接口,该接口提供一个 GetProperty<T> 方法,用作访问由通道堆栈中的通道公开的任意功能的分层机制。扩展 IChannel 的五种通道形状为:

1.IInputChannel:用于接收消息

2.IOutputChannel:用于发送消息

3.IRequestChannel:用于发送请求

4.IReplyChannel:用于发送回复

5.IDuplexChannel:用于双向消息传递

它们之间的关系如图4所示:

TerryLee_WCF_25

图 4

其实可以看出,IDuplexChannel接口是IInputChannel和IOutputChannel接口的联合,所有的通道形状都同时扩展了ICommunicationObject和IChannel。这5种通道模型分别对应于不同的消息交换模式,在使用数据报模式时,消息发送方通道实现了IOutputChannel接口,而消息接收方通道实现了IInputChannel接口;在请求响应模式中,客户端通道实现IRequestChannel接口,而服务通道实现IReplyChannel接口;在双工通信模式中,由于双方都能发送和接收消息,客户端和服务通道实现了IDuplexChannel接口,如图5所示:

TerryLee_WCF_29

图 5

服务端通道

在通道对象模型中,除了IChannel接口,另外一个接口IChannelListener用于消息的接收端,通过绑定来生成通道侦听器(在绑定中有关于协议、编码和传输的信息,关于绑定可以参考WCF专题系列(6):消息如何传递之绑定Part 1),用于侦听传入的消息。通道侦听器负责创建通道并从下面的层或者从网络接收消息,收到的消息将借助于通道侦听器所创建的通道传送到上面的层中。整个过程如图6所示:

TerryLee_WCF_26

图 6

在WCF的内部,对于消息的每一个处理(即通道堆栈中的通道),都会对应一个内部的通道侦听器,如针对事务处理的TransactionChannelListener和使用TCP传输的TcpChannelListener,分别用于创建各自对应的通道。

客户端通道

在WCF的客户端,通道的创建使用通道工厂,创建的这些通道负责获取来自上一层的消息,对消息进行必要的处理,然后将消息发送到下一层,如图7所示:

TerryLee_WCF_27

图 7

在WCF内部,同样对于消息的每一个处理,都会有相应的通道工厂,如使用TCP传输的TcpChannelFactory,用于创建对应的通道。

总结

本文详细介绍了WCF中的通道编程模型以及关于通道、通道监听器和通道工厂等,大多数都是纯理论的知识,在下一篇文章中,将会通过一个示例来加深对于本文所讲知识的认识。

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2008-11-11 22:36 TerryLee 阅读(6222) 评论(35)  编辑 收藏 网摘 所属分类: [04]  WCF后传

  回复  引用  查看    
#1楼2008-11-11 22:54 | 李永京      
沙发坐上...
  回复  引用    
#2楼2008-11-11 23:20 | 出差[未注册用户]
不得不佩服,你的精力真的很强,能告诉我你每天有多少时间用于学习?几点睡?几点起床呀?大哥我真是服了你,你怎么如此强呀!
  回复  引用  查看    
#3楼2008-11-11 23:24 | Anytao      
@出差
我帮你回答,他不是人,每天几乎不睡觉,晚上3点是家常便饭,而且工作还不打盹。爱好抽烟和喝酒,能够提神醒目。

最重要的,他看见新玩意就心痒难忍,汇报完毕。

  回复  引用    
#4楼2008-11-11 23:34 | 零零发[未注册用户]
@Anytao
天哪,这样的人是人吗?唉,相比之下汗颜!
一句话:搞技术的苦呀!不这样能成为牛人么?可以根据楼主的经历写一本《牛人是如何炼成的》的书籍,绝对畅销。

搞技术的熬夜看书
搞市场的熬夜陪客户吃喝泡睡
这个世界人难做

  回复  引用  查看    
#5楼2008-11-12 01:17 | 怪怪      
@Anytao
经典 :P

  回复  引用  查看    
#6楼2008-11-12 08:25 | Steven Chen      
那些图很漂亮
  回复  引用  查看    
#7楼2008-11-12 09:23 | Artech      
@Anytao
铁人呀:)

  回复  引用  查看    
#8楼2008-11-12 09:35 | good man      
你的写博客是用什么工具写的啊!
很好,一定要向你学习啊!

  回复  引用  查看    
#9楼2008-11-12 09:42 | DaveLin      
加油,支持
  回复  引用  查看    
#10楼2008-11-12 10:31 | 红魔      
跟踪TerryLee ,好几年了,可就是跟不上啊,郁闷。。。你太快了
  回复  引用  查看    
#11楼[楼主]2008-11-12 11:04 | TerryLee      
@李永京
小李同志每次都坐沙发,呵呵,欢迎:)

  回复  引用  查看    
#12楼[楼主]2008-11-12 11:05 | TerryLee      
@出差
呵呵,其实没有Anytao说的那么夸张,我会保证每天睡觉6个小时,时间想要挤,总会有的:)

  回复  引用  查看    
#13楼[楼主]2008-11-12 11:05 | TerryLee      
@Anytao
Anytao,又诋毁我的形象了,呵呵,鄙视一下:)

  回复  引用  查看    
#14楼[楼主]2008-11-12 11:06 | TerryLee      
@零零发
呵呵,其实Anytao太夸张了……

不过搞IT的,不学习真不行啊,没办法。

  回复  引用  查看    
#15楼[楼主]2008-11-12 11:07 | TerryLee      
@怪怪
怪怪也来了,呵呵,别听Anytao瞎扯:)

  回复  引用  查看    
#16楼[楼主]2008-11-12 11:07 | TerryLee      
@Steven Chen
呵呵,用Visio画的:)

  回复  引用  查看    
#17楼[楼主]2008-11-12 11:08 | TerryLee      
@good man
我用Windows Live Writer写的:)

  回复  引用  查看    
#18楼[楼主]2008-11-12 11:08 | TerryLee      
@DaveLin
谢谢支持:)

  回复  引用  查看    
#19楼[楼主]2008-11-12 11:09 | TerryLee      
@Artech
Artech每次都来支持,呵呵,Anytao是瞎说的,别信他:)

  回复  引用  查看    
#20楼[楼主]2008-11-12 11:09 | TerryLee      
@红魔
呵呵,太客气了,共同进步:)

  回复  引用  查看    
#21楼2008-11-12 11:13 | 食草笨笨熊      
WCF园子里有好几个系列了,但是还是老大写的比较通俗易懂,
武功之大成者当回归淳朴,实在佩服

  回复  引用  查看    
#22楼2008-11-12 11:21 | 食草笨笨熊      
而且老大怎么会涉猎的范围这么广啊,基本上学。net看你一个人的blog就够了
  回复  引用  查看    
#23楼[楼主]2008-11-12 11:24 | TerryLee      
@食草笨笨熊
呵呵,太过奖了,其实这些东西也不算广,都是.NET Framework中的,而且在开发中都会遇到的:)

  回复  引用  查看    
#24楼2008-11-12 12:02 | redfox105      
想问下各位,你们部署WCF的时候一般是用.net framework 3.0
还是.net framework 3.5啊?
按理说,.net framework 3.5 sp1已经出来了,应该要这个,但是发现3.5 sp1
有230多M,而且安装的时候还必须连上internet ,很麻烦.
所以现在的项目还不敢用wcf,不知道大家有什么好的办法解决这个问题.

  回复  引用  查看    
#25楼[楼主]2008-11-12 12:35 | TerryLee      
@redfox105
其实大多数情况下,都会用.NET Framework 3.5,但是不一定非要安装.NET Framework 3.5 SP1的。

  回复  引用  查看    
#26楼2008-11-12 12:49 | 自强不息      
楼主对net掌握太全面了,佩服
  回复  引用  查看    
#27楼2008-11-12 13:13 | redfox105      
@TerryLee
3.5的安装文件也要200多M吧,不知道需不需要连上网才能装

  回复  引用  查看    
#28楼[楼主]2008-11-12 13:30 | TerryLee      
@自强不息
其实没有,.NET是非常庞大的,还有很多东西不了解:)

  回复  引用  查看    
#29楼[楼主]2008-11-12 13:30 | TerryLee      
@redfox105
我记得有单独下载安装的:)

  回复  引用  查看    
#30楼2008-11-12 13:38 | Henllyee Cui      
受益匪浅
  回复  引用    
#31楼2008-11-12 16:07 | Duron800[未注册用户]
支持,期待下回的内容。
  回复  引用  查看    
#32楼[楼主]2008-11-12 23:46 | TerryLee      
@Henllyee Cui
:)

  回复  引用  查看    
#33楼[楼主]2008-11-12 23:47 | TerryLee      
@Duron800
谢谢支持,下篇将会用一个实例来介绍通道模型:)

  回复  引用  查看    
#34楼2008-11-13 16:06 | lzlynn      
呵呵,服了。
  回复  引用  查看    
#35楼[楼主]2008-11-15 00:37 | TerryLee      
@lzlynn
有什么问题呢:)

发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1331035





相关文章:

相关链接: