您的位置:知识库 » .NET技术

[WCF中的Binding模型]之二: 信道与信道栈(Channel and Channel Stack)

作者: Artech  来源: 博客园  发布时间: 2008-12-15 12:17  阅读: 6410 次  推荐: 0   原文链接   [收藏]  

WCF采用基于消息交换的通信方式,而绑定则实现了所有的通信细节。绑定通过创建信道栈实现了消息的编码与传输,以及对WS-*协议的实现。在这一节中,我们就来着重介绍WCF中的信道和信道栈。在正式开始对信道和信息栈的介绍之前,我们先来介绍两个重要的类型:CommunicationObject和DefaultCommunicationTimeouts。

CommunicationObject与DefaultCommunicationTimeouts

WCF绑定模型涉及多种类型的组件,比如信道、信道监听器、信道工厂等等。从功能上讲,这些对象都是为通信服务的,我们可以把它们称为通信对象(Communication Object)。对于这些通信对象来说,在通信不同的阶段,它们往往具有不同的状态;从整个通信的生命周期来看,在不同阶段过渡的过程中,它们具有一些相似的状态转换方式。

WCF定义了一个特殊的接口,System.ServiceModel.ICommunicationObject,来管理通信对象的状态和状态的转换。下面是ICommunicationObject的定义:

public interface ICommunicationObject
{
    // Events
    event EventHandler Closed;
    event EventHandler Closing;
    event EventHandler Faulted;
    event EventHandler Opened;
    event EventHandler Opening;

    // Methods
    void Open();
    void Open(TimeSpan timeout);
    IAsyncResult BeginOpen(AsyncCallback callback, object state);
    IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state);
    void EndOpen(IAsyncResult result);

    void Close();
    void Close(TimeSpan timeout);
    IAsyncResult BeginClose(AsyncCallback callback, object state);
    IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state);
    void EndClose(IAsyncResult result);

    void Abort();

    // Properties
    CommunicationState State { get; }
}

ICommunicationObject的State属性,表示通信对象当前所处的状态。该属性通过一个名为System.ServiceModel.CommunicationState的枚举类型表示,通信对象典型的六种状态都定义在CommunicationState中:被创建(Created)、正被开启(Opening)、已经被开启(Opened)、正被关闭(Closing)、已经被关闭(Closed)已经出错(Faulted)。

public enum CommunicationState
{
    Created,
    Opening,
    Opened,
    Closing,
    Closed,
    Faulted
}

ICommunicationObject定义了以下三种类型的成员:

  • 事件:当正在进行状态转化,或者是状态转换成功,会触发相应的事件。通过注册相应的事件,可以在某个状态转换环节中注入你需要的处理操作。
  • 方法:定义了三种类型的操作:开启(open)、关闭(close)、中止(abort)。关于“关闭”和“中止”在功能上具有相似之出,都是断开连接、回收对象。不过它们具有不同之处,很多英文文章或书籍将“关闭(close)”成为“graceful shutdown(优雅地关闭)”,而将“中止(abort)”描述为“immediate shutdown(立即关闭)”。那我们关闭电脑来说,前面一种是通过操作系统进行关闭,后一种则是直接切断电源。对于前一种方式,在关闭过程中,会进行一些IO操作。
  • 属性:在上面已经提到,属性State代表通信对象当前所处的状态。

由于WCF处理的是跨应用程序域(Application Domain)、跨机器甚至是跨网络的通信。所以WCF服务调用的大部分时间都在进行象网络传输这样的IO操作,对于这种IO绑定(IO bound)的操作,对于多线程、异步的考虑肯定是可以不免的,所以ICommunicationObject中的开启和关闭操作,既定义了一个的同步方法,也按照异步编程模型(APM:Asynchronous Programming Mode)定义了异步方法。

除了简单定义ICommunicationObject接口之外,WCF还定义了一个实现了该接口的基类:System.ServiceModel.Channels.CommunicationObject。

public abstract class CommunicationObject : ICommunicationObject 
{ 
... 
} 

在WCF体系中,很多的基于通信的基类都继承自CommunicationObject,比如信道的基类System.ServiceModel.Channels.ChannelBase;信道工厂和信道监听器的基类System.ServiceModel.Channels.ChannelManagerBase;ServiceHost的基类System.ServiceModel.ServiceHostBase;信道分发器的基类System.ServiceModel.Dispatcher.ChannelDispatcherBase;等等。大体的继承结构如3-8所示 的类图所示。

image

3-8 CommunicationObject继承关系

由于WCF往往需要跨域网络进行服务的访问,较之一般的方法调用,服务访问的所花的时间往往较长,所以对超时的处理显得异常重要。比如对于消息的发送,可能由于网络的故障,该消息在一端时间内根本无法成功发送,客户端程序不可能无限制地等待下去。一般的情况下,我们会设定一个操作执行的所允许的最大时限,一旦超时则取消操作,并进行相应的超时处理。

我们回顾一下ICommunicationObject的Open和BeginOpen方法,我们会发现它们各有两个重载,其中一个具有的TimeSpan类型的timeout参数,另一个则没有。在这里的timeout参数实际上代表Open方法执行的超时时间,如果Open操作执行的时间过长,一旦超过了该事件,操作将被立即中止。

public interface ICommunicationObject 
{ 
void Open(); 
void Open(TimeSpan timeout); 
IAsyncResult BeginOpen(AsyncCallback callback, object state); 
IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state); 
... ... 
} 

可能读者会问,对于没有timeout参数的操作,比如无参的Open方法,是否意味着没有这样的超时限制,操作将会一直执行下去直到操作正常结束呢?答案是否定的,实际上,对于没有显式指定超时时限的操作,采用的是默认的超时时限。WCF为所有需要默认超时时限的通信对象定义了一个接口:System.ServiceModel.IDefaultCommunicationTimeouts。在IDefaultCommunicationTimeouts中定一个了四个Timeout属性,分别定义了开启、关闭、发送、接收四大操作的超时时限。

public interface IDefaultCommunicationTimeouts
{
    // Properties 
    TimeSpan CloseTimeout { get; }
    TimeSpan OpenTimeout { get; }
    TimeSpan ReceiveTimeout { get; }
    TimeSpan SendTimeout { get; }
}

很多的基于通信的基类都实现了IDefaultCommunicationTimeouts接口,比如信道的基类System.ServiceModel.Channels.ChannelBase信道工厂和信道监听器的基类System.ServiceModel.Channels.ChannelManagerBase;以及所有绑定对象的基类System.ServiceModel.Channels.Binding等等。

0
0

.NET技术热门文章

    .NET技术最新文章

      最新新闻

        热门新闻