当前位置:编程学习 > 网站相关 >>

WCF后续之旅(2): 如何对Channel Layer进行扩展——创建自定义Channel

在html" target=_blank>上一篇文章中,我们通过一个直接借助BasicHttpBinding对象实现Client和Server端进行通信的例子,对WCF channel layer进行了一个大致上的介绍。由此引出了一些列通信相关的概念和对象,比如Channel,Output channel, Input channel,Request channel, Reply Channel,Duplex channel, Channel Shape,Channel manager,Channel factory, Channel listener, Binding element 等。通过这些元素,我们很容易地实现对WCF channel layer进行扩展。

对channel layer进行扩展一般适用于当你的需求通过现有的Binding,或者channel不能实现,而需要自定义一些channel来实现你所需的功能。不如现在的WCF系统定义的Channel中没有实现对Message body的压缩功能。你可以就需要将此功能定义到一个custom channel中,然后将其注入到channel stack中。一般来说,仅仅创建custom channel是不够的,因为在runtime, channel是通过Channel manager进行创建的,所以你需要创建对应的Channel factory(如何对发送方进行扩展)或者Channel listener(如果对接受方进行扩展)。而Channel factory和channel listener最终又是通过Binding element进行创建的,所以你还需要创建相应的Binding element。(Binding element=〉Channel factory&Channel listener=>Channel)

在本章节中,我们将继续讨论WCF channel layer。我们将通过如何创建和应用custom channel来介绍channel layer一些知识。

一、ICommunicationObject 和 CommunicationObject

我们

 

知道WCF channel layer的绝大部分对象,比如Channel,Channel factory,Channel listener,从功能上讲都是用于通信(Communication)的对象,对传统的communication object,比如socket,他们往往都具有通过状态和状态转化规则(状态机:State machine)。这些状态包括Creating、Created、Opening、Opened、Closing、Closed等等。为了统一管理这些状态和状态之间的转化,WCF定义个一个特殊的Interface:ICommunicationObject

   1: public interface ICommunicationObject
   2: {
   3:     // Events
   4:     event EventHandler Closed;
   5:     event EventHandler Closing;
   6:     event EventHandler Faulted;
   7:     event EventHandler Opened;
   8:     event EventHandler Opening;
   9: 
  10:     // Methods
  11:     void Abort();
  12:     IAsyncResult BeginClose(AsyncCallback callback, object state);
  13:     IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state);
  14:     IAsyncResult BeginOpen(AsyncCallback callback, object state);
  15:     IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state);
  16:     void Close();
  17:     void Close(TimeSpan timeout);
  18:     void EndClose(IAsyncResult result);
  19:     void EndOpen(IAsyncResult result);
  20:     void Open();
  21:     void Open(TimeSpan timeout);
  22: 
  23:     // Properties
  24:     CommunicationState State { get; }
  25: }

ICommunicationObject定义了3种成员:

属性:State, 得到当前的状态,返回值是一个CommunicationState  枚举。
方法:同步、异步Open和Close方法。
事件:通过注册这些状态相关的Event,当时对象转化到对应的状态时执行相应操作。
WCF定义了一个abstract class: CommunicationObject直接实现了该Interface。CommunicationObject的实现统一的State machine。WCF channel layer的很多的class都直接或者间接的继承了这个class。你也可以让你的class继承该class。当你让你自己的class继承CommunicationObject的时候,在override 掉base相应的method的时候,强烈建议你先调用base对应的方法,CommunicationObject会帮你进行相应的State转换和触发相应的事件。

二、Channel 和Channel Shape
在上一篇文章中,我们讨论过了。在不同的消息交换模式(MEP)中,发送方和接受方的Channel扮演的角色是不相同的。我们并把这种不同MEP中消息交互双方Channel的结构差异表述为Channel shape。我们有四种不同的Channel shape:Datagram、Request/reply、Duplex和P2P。不同Channel shape中Channel的结构性差性通过实现不同的Channel interface来体现。

对于Datagram channel shape,采用了One-way的MEP。发送方的channel 必须实现IOutputChannel interface。该Interface的方法成员主要集中在用于发送message的Send方法(同步/异步):

   1: public interface IOutputChannel : IChannel, ICommunicationObject
   2: {
   3:     // Methods
   4:     IAsyncResult BeginSend(Message message, AsyncCallback callback, object state);
   5:     IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state);
   6:     void EndSend(IAsyncResult result);
   7:     void Send(Message message);
   8:     void Send(Message message, TimeSpan timeout);
   9: 
  10:     // Properties
  11:     EndpointAddress RemoteAddress { get; }
  12:     Uri Via { get; }
  13: }

与之相应是IInputChannel inteface,该Interface用于Datagram channel shape中接收方的channel定义。其主要方法成员主要集中在用于接收Message的Receive方法(同步/异步):

   1: public interface IInputChannel : IChannel, ICommunicationObject
   2: {
   3:     // Methods
   4:     IAsyncResult BeginReceive(AsyncCallback callback, object state);
   5:     IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state);
   6:     IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state);
   7:     IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state);
   8:     Message EndReceive(IAsyncResult result);
   9:     bool EndTryReceive(IAsyncResult result, out Message message);
  10:     bool EndWaitForMessage(IAsyncResult result);
  11:     Message Receive();
  12:     Message Receive(TimeSpan timeout);
  13:     bool TryReceive(TimeSpan timeout, out Message message);
  14:     bool WaitForMessage(TimeSpan timeout);
  15: 
  16:     // Properties
  17:     EndpointAddress LocalAddress { get; }
  18: }

注:无论对于同步或者异步方法,一般由两个重载,一个接收一个TimeSpan 作为参数,表是Send或者Receive允许的时间范围。而另一个没有该参数的方式,并不是建议你使用一个无限的TimeSpan,而是使用一个

补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,