zoukankan      html  css  js  c++  java
  • 深度通道编程模型

    引言

    从本质上说,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中的通道编程模型以及关于通道、通道监听器和通道工厂等,大多数都是纯理论的知识,在下一篇文章中,将会通过一个示例来加深对于本文所讲知识的认识。

  • 相关阅读:
    LeetCode对撞指针汇总
    167. Two Sum II
    215. Kth Largest Element in an Array
    2018Action Recognition from Skeleton Data via Analogical Generalization over Qualitative Representations
    题解 Educational Codeforces Round 84 (Rated for Div. 2) (CF1327)
    题解 JZPKIL
    题解 八省联考2018 / 九省联考2018
    题解 六省联考2017
    题解 Codeforces Round #621 (Div. 1 + Div. 2) (CF1307)
    题解Codeforces Round #620 (Div. 2)
  • 原文地址:https://www.cnblogs.com/qianyz/p/2649392.html
Copyright © 2011-2022 走看看