实例演示:自定义信道监听器 在前面一个实例演示中,我们创建了SimpleReplyChannel和SimpleDuplexSessionChannel这两个自定义信道。前者在请求-回复模式下以数据报形式在服务端实现对请求的接收和回复的发送,后者则是一个支持会话的双工信道。现在我们分别为它们创建相应的信道监听器。 创建自定义信道监听器基类 我们先来创建一个抽象的SimpleChannelListenerBase<TChannel>,它将作为接下来创建的数据报信道监听器和会话信道监听器的基类。如下面的代码所示,SimpleChannelListenerBase<TChannel>继承自ChannelListenerBase<TChannel>,用于打印当前执行方法的Print方法也定义其中。值得注意的是,我们依然需要按照如下的方式重写GetProperty<T>方法。 public abstract class SimpleChannelListenerBase<TChannel> : ChannelListenerBase<TChannel> where TChannel : class, IChannel { //其他成员 protected void Print(string methodName) { Console.WriteLine("{0}.{1}", this.GetType().Name, methodName); } public IChannelListener<TChannel> InnerChannelListener { get; private set; } public SimpleChannelListenerBase(BindingContext context) { this.InnerChannelListener = context.BuildInnerChannelListener<TChannel>(); } protected override IAsyncResult OnBeginAcceptChannel( TimeSpan timeout, AsyncCallback callback, object state) { this.Print("OnBeginAcceptChannel()"); return this.InnerChannelListener.BeginAcceptChannel( timeout, callback, state); } public override T GetProperty<T>() { return this.InnerChannelFactory.GetProperty<T>(); } } 和信道类似,用于创建信道的信道监听器存在一个管道中。当执行完某个操作之后,一般会调用后续信道监听器相应的操作,所以在SimpleChannelListenerBase<TChannel>中定义了一个只读属性InnnerChannelListener来表示下一个信道监听器。我们创建一个参数类型为System.Windows.Forms.BindingContext的构造函数,而InnnerChannelListener就是调用BindingContext的BuildInnerChannelListener<TChannel>方法创建的。 SimpleChannelListenerBase<TChannel>实现了定义在ChannelListenerBase<TChannel>中不包括信道创建(OnAcceptChannel和OnEndAcceptChannel)的所有抽象方法。实现方式和之前创建的自定义信道一样,即先调用Print方法将当前执行的方式名称打印出来,再调用InnerChannelListener相应的方法。 创建数据报信道监听器 接下来通过继承SimpleChannelListenerBase<TChannel>为自定义的回复信道SimpleReplyChannel创建对应的信道监听器。由于SimpleReplyChannel是一个数据报信道,我们将对应的信道监听器起名为SimpleDatagramChannelListener<TChannel>。只需要让它实现定义在ChannelListenerBase<TChannel>中但在SimpleChannelListenerBase<TChannel>中不曾实现的两个抽象方法OnAcceptChannel和OnEndAcceptChannel即可。如下面的代码所示,我们自定义的回复信道SimpleReplyChannel就是在这两个方法中被创建的。 public class SimpleDatagramChannelListener<TChannel> : SimpleChannelListenerBase<TChannel> where TChannel:class,IChannel { public SimpleDatagramChannelListener(BindingContext context) : base(context) { } protected override TChannel OnAcceptChannel(TimeSpan timeout) { IReplyChannel innerChannel = (IReplyChannel)this.InnerChannelListener.AcceptChannel(timeout); return new SimpleReplyChannel(this, innerChannel) as TChannel; } protected override TChannel OnEndAcceptChannel(IAsyncResult result) { IReplyChannel innerChannel = this.InnerChannelListener.EndAcceptChannel(result) as IReplyChannel; return new SimpleReplyChannel(this, innerChannel) as TChannel; } } 创建会话信道监听器 我们按照相同的方法来为自定义的会话信道SimpleDuplexSessionChannel创建对应的信道监听器SimpleSessionChannelListener。如下面的代码片段所示,也只需要实现OnAcceptChannel和OnEndAcceptChannel两个方法就行。 public class SimpleSessionChannelListener<TChannel> : SimpleChannelListenerBase<TChannel> where TChannel: class, IChannel { public SimpleSessionChannelListener(BindingContext context) : base(context) { this.Print("SimpleSessionChannelListener()"); } protected override TChannel OnAcceptChannel(TimeSpan timeout) { this.Print("OnAcceptChannel()"); IDuplexSessionChannel innerChannel = this.InnerChannelListener.AcceptChannel(timeout) as IDuplexSessionChannel; if(null != innerChannel) { return new SimpleDuplexSessionChannel(this, innerChannel) as TChannel; } reutrn default(TChannel); } protected override TChannel OnEndAcceptChannel(IAsyncResult result) { this.Print("OnEndAcceptChannel()"); IDuplexSessionChannel innerChannel this.InnerChannelListener.EndAcceptChannel(result) as IDuplexSessionChannel; if(null != innerChannel) { return new SimpleDuplexSessionChannel(this, innerChannel) as TChannel; } reutrn default(TChannel); } }