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

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

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

 

3.2. Channel Shape

在上面我们讨论了三种典型的消息交换模式(MEP),现在我们结合MEP再来讨论我们本节的主题:信道与信道栈。信道栈是消息交换的管道,在不同的消息交换模式下,这个管道在消息的发送端和接收端扮演着不同的角色。在数据报模式下,发送端的信道栈的作用是输出(Output)数据报,接收端则是输入(Input)数据报;对于请求恢复模式来说,发送端的作用是发送消息请求(Request),而接收端则是恢复(Reply)请求;而在双工通信模式下,消息交换的双方的地位完全是等价的,它们都具有 输出和输入的功能。

WCF通过一个特殊的术语来表述不同的消息交换模式对消息交换双方信道的不同要求:Channel Shape。Channel Shape按照适用的消息交换模式的不同,将信道进行了分类。WCF为这些信道定义了一些列的接口来描述其赋予的能力。这些接口包括:IOutputChannel、IInputChannel、IRequestChannel、IReplyChannel、 IDuplexChannel,它们均定义在System.ServiceModel.Channels命名空间下。

下面的表格简单列出了在不同的消息交换模式下,消息的发送方和接收方所使用的信道:

image

3-12所示的类图简单地描述了这些接口之间的层次结构:所有的接口均继承自IChannel接口,IDuplexChannel则继承了IOutputChannel和IInput、Channel两个接口。

image

3-12 Channel Shape

IOutChannel IInputChannel

接下来我们对这五种信道进行逐个介绍,先从IOutputChannel和IInputChannel开始。这两种类型的信道适用于基于数据报模式的消息交换中,发送端通过IOutputChannel发送消息,而接收端则通过IInputChannel接收消息。反应在接口的定义上,IOutputChannel主要定义的Send方法进行消息的发送,而IInputChannel则定义Receive方法进行消息的接收。先来看看IOutputChannel的定义:

public interface IOutputChannel : IChannel, ICommunicationObject
{
    // Methods
    void Send(Message message);
    void Send(Message message, TimeSpan timeout);

    IAsyncResult BeginSend(Message message, AsyncCallback callback, object state);
    IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state);
    void EndSend(IAsyncResult result);

    // Properties
    EndpointAddress RemoteAddress { get; }
    Uri Via { get; }
}

 

IOutputChannel的定义显得异常简单,两个重载的Send方法以同步的方式进行消息的发送,而两个BeginSend/EndSend则用于消息的异步发送。重载方法通过一个timeout参数区分。对于一个具体的信道类型来说,它一般会继承自ChannelBase类型。在上面我们已经介绍了ChannelBase实现了接口System.ServiceModel.IDefaultCommunicationTimeouts接口,所以它具有默认的发送超时时限(SendTimout)。因此,在调用没有timeout参数的Send或者BeginSend方法时,实际上采用的是自己默认的消息发送超时时限。

除了用于消息发送的方法成员之外,IOutputChannel还具有两个额外的属性成员:RemoteAddress和Via。RemoteAddress代表它试图访问的服务终结点的地址,而Via则代表是消息会真正发送的目的地址。RemoteAddress和Via所代表的地址 也就是在第二章介绍的逻辑地址和物理地址。在一般的情况下,这两个地址是相同的,在需要进行手工寻址的情况下,它们可以是完全不同的两个地址,关于WCF的寻址,请参阅第二章。

了解了IOutputChannel的定义,我想读者应该可以大体上猜得到与之相对的IInputChannel的定义了。IInputChannel用于消息的接收,所以定义了一系列Receive和BeginReceive/EndReceive方法用于同步或者异步的方式接收消息。不过IInputChannel较之IOutputChannel稍微复杂一些,它还定义了两组额外的方法成员:TryReceive和BeginTryReceive/EndTryReceive,以及WaitForMessage和BeginWaitForMessage/EndWaitForMessage。

public interface IInputChannel : IChannel, ICommunicationObject
{
    // Methods
    Message Receive();
    Message Receive(TimeSpan timeout);
    IAsyncResult BeginReceive(AsyncCallback callback, object state);
    IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state);
    Message EndReceive(IAsyncResult result);

    bool TryReceive(TimeSpan timeout, out Message message);
    IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state);
    bool EndTryReceive(IAsyncResult result, out Message message);

    bool WaitForMessage(TimeSpan timeout);
    IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state);
    bool EndWaitForMessage(IAsyncResult result);

    // Properties
    EndpointAddress LocalAddress { get; }
}

调用TryReceive和BeginTryReceive/EndTryReceive方法,在一个给定的时间范围内尝试去接收请求消息,而WaitForMessage和BeginWaitForMessage/EndWaitForMessage则用于检测是否有请求消息抵达。此外IOutputChannel的LocalAddress属性代表信道所属终结点的地址。

IRequestChannelIReplyChannel

IRequestChannel和IReplyChannel定义了在请求-回复模式下消息发送方和接收方对信道的基本要求。对于消息的发送方的信道来说,它的主要功能就是向接收方发送消息请求并接收接收方发回的回复消息;与之相对,消息接收方负责对消息请求的接收,以及对回复消息的发送。

所以IRequestChannel的主要方法成员就是一组Request和BeginRequest/EndRequest方法用于同步和异步下请求的发送。整个IRequestChannel的定义如下所示 :

public interface IRequestChannel : IChannel, ICommunicationObject
{
    // Methods
    Message Request(Message message);
    Message Request(Message message, TimeSpan timeout);

    IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state);
    IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state);
    Message EndRequest(IAsyncResult result);

    // Properties
    EndpointAddress RemoteAddress { get; }
    Uri Via { get; }
}

和IOutputChannel接口一样,Request和BeginRequest方法各有两个重载,它们通过一个timeout参数进行区分。Timeout参数代表请求发送(同步或者异步)的超时时限,如果没有此参数,则采用默认的超时时限。两个属性RemoteAddress和Via则分别表示目的终结点的地址,以及消息真正发送的目的地址。换句话说,RemoteAddress和Via所代表的是在第二章介绍的逻辑地址和物理地址。

IReplyChannel和IInputChannel的成员结构很相似,不过IInputChannel的主要功能就就是单纯的接收消息,所以定义了一系列Receive相关的方法;而IReplyChannel负责接受请求,所以IReplyChannel围绕着ReceiveRequest展开。包括3种类型的ReceiveRequest方法:ReceiveRequest和BeginReceiveRequest/EndReceiveRequest,TryReceiveRequest和BeginTryReceiveRequest/EndTryReceiveRequest和WaitForRequest和BeginWaitForRequest和EndWaitForRequest。

public interface IReplyChannel : IChannel, ICommunicationObject
{
    // Methods 

    RequestContext ReceiveRequest();
    RequestContext ReceiveRequest(TimeSpan timeout);
    IAsyncResult BeginReceiveRequest(AsyncCallback callback, object state);
    IAsyncResult BeginReceiveRequest(TimeSpan timeout, AsyncCallback callback, object state);
    RequestContext EndReceiveRequest(IAsyncResult result);

    bool TryReceiveRequest(TimeSpan timeout, out RequestContext context);
    IAsyncResult BeginTryReceiveRequest(TimeSpan timeout, AsyncCallback callback, object state);
    bool EndTryReceiveRequest(IAsyncResult result, out RequestContext context);

    bool WaitForRequest(TimeSpan timeout);
    IAsyncResult BeginWaitForRequest(TimeSpan timeout, AsyncCallback callback, object state);
    bool EndWaitForRequest(IAsyncResult result);

    // Properties
    EndpointAddress LocalAddress { get; }
}

对于IReplyChannel来说,有一点需要特别说明。和我们一般想象的不一样,不论是ReceiveRequest的返回类型,还是EndTryReceiveRequest的输出参数类型,并不是一个Message类型,而是一个RequestContext类型。RequestContext可以看成是请求和回复之间的一道桥梁,通过RequestContext既可以获取请求消息(通过RequestContext的RequestMessage属性获取以Message类型返回德请求消息),也可以向请求端发送回复消息(在RequestContext定义了一系列Reply和BeginReply/EndReply方法将作为参数的Message对象发回请求端)。

IDuplexChannel

由于在双工模式下的消息交换中,消息的发送端和接收端具有相同的行为和功能:消息的发送和接收,所以基于双工模式的信道, IDuplexChannel兼具IOutputChannel和IInputChannel的特性。反映在接口的定义上就是IDuplexChannel同时继承了IOutputChannel和IInputChannel:

public interface IDuplexChannel : IInputChannel, IOutputChannel, IChannel, ICommunicationObject
{
}

WCF中的绑定模型:
[WCF中的Binding模型]之一: Binding模型简介
[WCF中的Binding模型]之二: 信道与信道栈(Channel and Channel Stack)
[WCF中的Binding模型]之三:信道监听器(Channel Listener)
[WCF中的Binding模型]之四:信道工厂(Channel Factory)
[WCF中的Binding模型]之五:绑定元素(Binding Element)
[WCF中的Binding模型]之六:从绑定元素认识系统预定义绑定

0
0

.NET技术热门文章

    .NET技术最新文章

      最新新闻

        热门新闻