• WCF-绑定模型(二)


        二、绑定元素

          每一个类型的绑定最重要的就是绑定元素了,每个绑定的功能特性都由绑定元素决定。BasicHttpBinding由用于编码的TextMessageEncodingBindingElement和用于httpp协议传输的HttpTransportBindingElement 构成。

    NetTcpBinding由下列绑定元素组成,可以看出NetTcpBinding支持事务、二进制编码、信道安全、底层使用Tcp协议传输。

    TransactionFlowBindingElement
    BinaryMessageEncodingBindingElement
    WindowsStreamSecurityBindingElement
    TcpTransportBindingElement

      可以通绑定的CreateBindingElements方法获取当前绑定元素。

     WSHttpBinding bind = new WSHttpBinding();
     foreach (var ele in bind.CreateBindingElements())
     {
        Console.WriteLine("{0}", ele.GetType().Name);
     }

       整个绑定模型可以由下面这张图表示:

    绑定元素能够创建信道管理器,再由信道管理器创建信道。信道管理器就是前面说到的信道监听器、信道工厂的简称,因为它们都继承自ChannelManagerBase。信道位于最底层,提供对消息的某种功能处理,对消息进行编码、传输是最基本的两种信道。

      三、创建自定义信道

           myChannelBase,继承信道基类ChannelBase,由一个InnerChannel表示下一个信道。所以方法都是简单输出当前类的名称,并调用下一个信道的方法来实现,本信道是打酱油的,只为看出后续绑定执行流程。

    class myChannelBase:ChannelBase
        {
    
            public ChannelBase InnerChannel { get; private set; }
            public myChannelBase(ChannelManagerBase channelManager, ChannelBase InnerChannel)
                : base(channelManager)
            {
                this.InnerChannel = InnerChannel;
            }
    
            public override T GetProperty<T>()
            {
                print("GetProperty<T>");
                return InnerChannel.GetProperty<T>();
            }
    
            protected void print(string methodname)
            {
                Console.WriteLine("{0}:{1}", this.GetType().Name, methodname);
            }
            protected override void OnAbort()
            {
                print("OnAbort");
                InnerChannel.Abort();
            }
    
            protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
            {
                print("OnBeginClose");
                return InnerChannel.BeginClose(timeout, callback, state);
            }
    
            protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
            {
                print("OnBeginOpen");
                return InnerChannel.BeginOpen(timeout, callback, state);
            }
    
            protected override void OnClose(TimeSpan timeout)
            {
                print("OnClose");
                InnerChannel.Close(timeout);
            }
    
            protected override void OnEndClose(IAsyncResult result)
            {
                print("OnEndClose");
                InnerChannel.EndClose(result);
            }
    
            protected override void OnEndOpen(IAsyncResult result)
            {
                print("OnEndOpen");
                InnerChannel.EndOpen(result);
            }
    
            protected override void OnOpen(TimeSpan timeout)
            {
                print("OnOpen");
                InnerChannel.Open(timeout);
            }
        }
    View Code

         myRequestChannel:请求信道,继承myChannelBase,并实现IRequestChannel。构造函数传入信道管理器,以及下一个信道。后面由myChannelFactory创建。

     class myRequestChannel:myChannelBase,IRequestChannel
        {
            public IRequestChannel InnerRequestChannel
            {
                get 
                {
                    return (IRequestChannel)base.InnerChannel;
                }
            }
            public myRequestChannel(ChannelManagerBase channelManager, IRequestChannel InnerRequestChannel)
                : base(channelManager, (ChannelBase)InnerRequestChannel)
            {
                base.print("myRequestChannel()");
            }
            public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
            {
                base.print("BeginRequest(message,timeout,callback,state)");
                return InnerRequestChannel.BeginRequest(message, timeout, callback, state);
            }
    
            public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state)
            {
                base.print("BeginRequest(message,callback,state)");
                return InnerRequestChannel.BeginRequest(message, callback, state);
            }
    
            public Message EndRequest(IAsyncResult result)
            {
                base.print("EndRequest(result)");
                return InnerRequestChannel.EndRequest(result);
            }
    
            public EndpointAddress RemoteAddress
            {
                get { return InnerRequestChannel.RemoteAddress; }
            }
    
            public Message Request(Message message, TimeSpan timeout)
            {
                base.print("Request(message,timeout)");
                return InnerRequestChannel.Request(message, timeout);
            }
    
            public Message Request(Message message)
            {
                base.print("Request(message)");
                return InnerRequestChannel.Request(message);
            }
    
            public Uri Via
            {
                get { return InnerRequestChannel.Via; }
            }
        }
    View Code

        myReplyChannel:回复信到,继承myChannelBase,并实现IReplyChannel。构造函数传入信道管理器,以及下一个信道。后面由myChannelListener创建。

     class myReplyChannel:myChannelBase,IReplyChannel
        {
            public IReplyChannel InnerRepleyChannel
            {
                get
                {
                   return (IReplyChannel)base.InnerChannel;
                }
            }
            public myReplyChannel(ChannelManagerBase channelManager, IReplyChannel InnerRepleyChannel)
                : base(channelManager, (ChannelBase)InnerRepleyChannel)
            {
                base.print("myReplyChannel()");
            }
    
            public IAsyncResult BeginReceiveRequest(TimeSpan timeout, AsyncCallback callback, object state)
            {
                base.print("BeginReceiveRequest(timeout, callback, state)");
                return InnerRepleyChannel.BeginReceiveRequest(timeout, callback, state);
            }
    
            public IAsyncResult BeginReceiveRequest(AsyncCallback callback, object state)
            {
                base.print("BeginReceiveRequest(callback, state)");
                return InnerRepleyChannel.BeginReceiveRequest(callback, state);
            }
    
            public IAsyncResult BeginTryReceiveRequest(TimeSpan timeout, AsyncCallback callback, object state)
            {
                base.print("BeginTryReceiveRequest(timeout,callback, state)");
                return InnerRepleyChannel.BeginTryReceiveRequest(timeout,callback, state);
            }
    
            public IAsyncResult BeginWaitForRequest(TimeSpan timeout, AsyncCallback callback, object state)
            {
                base.print("BeginWaitForRequest(timeout,callback, state)");
                return InnerRepleyChannel.BeginWaitForRequest(timeout, callback, state);
            }
    
            public RequestContext EndReceiveRequest(IAsyncResult result)
            {
                base.print("EndReceiveRequest(result)");
                return InnerRepleyChannel.EndReceiveRequest(result);
            }
    
            public bool EndTryReceiveRequest(IAsyncResult result, out RequestContext context)
            {
                base.print("EndTryReceiveRequest(result,out context)");
                return InnerRepleyChannel.EndTryReceiveRequest(result, out context);
            }
    
            public bool EndWaitForRequest(IAsyncResult result)
            {
                base.print("EndWaitForRequest(result)");
                return InnerRepleyChannel.EndWaitForRequest(result);
            }
    
            public EndpointAddress LocalAddress
            {
                get { return InnerRepleyChannel.LocalAddress; }
            }
    
            public RequestContext ReceiveRequest(TimeSpan timeout)
            {
                base.print("ReceiveRequest(timeout)");
                return InnerRepleyChannel.ReceiveRequest(timeout);
            }
    
            public RequestContext ReceiveRequest()
            {
                base.print("ReceiveRequest()");
                return InnerRepleyChannel.ReceiveRequest();
            }
    
            public bool TryReceiveRequest(TimeSpan timeout, out RequestContext context)
            {
                base.print("TryReceiveRequest(timeout,out context)");
                return InnerRepleyChannel.TryReceiveRequest(timeout, out context);
            }
    
            public bool WaitForRequest(TimeSpan timeout)
            {
                base.print("WaitForRequest(timeout)");
                return InnerRepleyChannel.WaitForRequest(timeout);
            }
        }
    View Code

    四、自定义信道监听器
     myChannelListenerBase,自定义的信道监听器基类,最重要的作用就是在构造函数创建下一个信道监听器。

     class myChannelListenerBase<TChannel> : ChannelListenerBase<TChannel> where TChannel : class,IChannel
        {
            public IChannelListener<TChannel> InnreListener
            {
                get;
                private set;
            }
            public myChannelListenerBase(BindingContext context)
            {
                InnreListener = context.BuildInnerChannelListener<TChannel>();
            }
    
            protected void print(string methodname)
            {
                Console.WriteLine("{0}:{1}", this.GetType().Name, methodname);
            }
    
            protected override TChannel OnAcceptChannel(TimeSpan timeout)
            {
                print("OnAcceptChannel(timeout)");
                return InnreListener.AcceptChannel(timeout);
            }
    
            protected override IAsyncResult OnBeginAcceptChannel(TimeSpan timeout, AsyncCallback callback, object state)
            {
                print("OnBeginAcceptChannel(timeout,callback,state)");
                return InnreListener.BeginAcceptChannel(timeout, callback, state);
            }
    
            protected override TChannel OnEndAcceptChannel(IAsyncResult result)
            {
                print("OnEndAcceptChannel(result)");
                return InnreListener.EndAcceptChannel(result);
            }
    
            protected override IAsyncResult OnBeginWaitForChannel(TimeSpan timeout, AsyncCallback callback, object state)
            {
                print("OnBeginWaitForChannel(timeout,callback,state)");
                return InnreListener.BeginWaitForChannel(timeout, callback, state);
            }
    
            protected override bool OnEndWaitForChannel(IAsyncResult result)
            {
                print("OnEndWaitForChannel(result)");
                return InnreListener.EndWaitForChannel(result);
            }
    
            protected override bool OnWaitForChannel(TimeSpan timeout)
            {
                print("OnWaitForChannel(timeout)");
                return InnreListener.WaitForChannel(timeout);
            }
    
            public override Uri Uri
            {
                get { return InnreListener.Uri; }
            }
    
            protected override void OnAbort()
            {
                print("OnAbort()");
                InnreListener.Abort();
            }
    
            protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
            {
                print("OnBeginClose(timeout,callback,state)");
                return InnreListener.BeginClose(timeout, callback, state);
            }
    
            protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
            {
                print("OnBeginOpen(timeout,callback,state)");
                return InnreListener.BeginOpen(timeout, callback, state);
            }
    
            protected override void OnClose(TimeSpan timeout)
            {
                print("OnClose(timeout)");
                InnreListener.Close(timeout);
            }
    
            protected override void OnEndClose(IAsyncResult result)
            {
                print("OnEndClose(result)");
                InnreListener.EndClose(result);
            }
    
            protected override void OnEndOpen(IAsyncResult result)
            {
                print("OnEndOpen(result)");
                InnreListener.EndOpen(result);
            }
    
            protected override void OnOpen(TimeSpan timeout)
            {
                print("OnOpen(timeout)");
                InnreListener.Open(timeout);
            }
        }
    View Code

    myChannelListener,OnAcceptChannel方法中创建三中提到的myReplyChannel。

    class myChannelListener<TChannel> : myChannelListenerBase<TChannel> where TChannel : class,IChannel
        {
    
            public myChannelListener(BindingContext context)
                : base(context)
            { 
            }
    
            protected override TChannel OnAcceptChannel(TimeSpan timeout)
            {
                print("OnAcceptChannel(timeout)");
                IReplyChannel replyCHannel = (IReplyChannel)InnreListener.AcceptChannel(timeout);
                return (new myReplyChannel(this, replyCHannel) as TChannel);
            }
    
    
            protected override TChannel OnEndAcceptChannel(IAsyncResult result)
            {
                print("OnEndAcceptChannel(result)");
                IReplyChannel replychannel= InnreListener.EndAcceptChannel(result) as IReplyChannel;
                return new myReplyChannel(this, replychannel) as TChannel;
            }
    
        }
    View Code

    五、自定信道工厂

      myChannelFactoryBase,继承自ChannelFactoryBase,工厂基类,主要作用是创建下一个信道工厂。

    class myChannelFactoryBase<TChannel> : ChannelFactoryBase<TChannel>
        {
            public IChannelFactory<TChannel> InnerFactory
            {
                get;
                private set;
            }
    
            protected void print(string methodname)
            {
                Console.WriteLine("{0}:{1}", this.GetType().Name, methodname);
            }
            public myChannelFactoryBase(BindingContext context)
            {
                print("myChannelFactoryBase(context)");
               InnerFactory=  context.BuildInnerChannelFactory<TChannel>();
            }
    
            protected override TChannel OnCreateChannel(EndpointAddress address, Uri via)
            {
                print("OnCreateChannel(address,via)");
                return InnerFactory.CreateChannel(address,via);
            }
    
            protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
            {
                print("OnBeginOpen(timeout,callback,state)");
                return InnerFactory.BeginOpen(timeout, callback, state);
            }
    
            protected override void OnEndOpen(IAsyncResult result)
            {
                print("OnEndOpen(result)");
                InnerFactory.EndOpen(result);
            }
    
            protected override void OnOpen(TimeSpan timeout)
            {
                print("OnOpen(timeout)");
                InnerFactory.Open(timeout);
            }
        }
    View Code

    myChannelFactory,自定义信道工厂,创建三中提到的myRequestChannel。

    class myChannelFactory<TChannel> : myChannelFactoryBase<TChannel>
        {
    
            public myChannelFactory(BindingContext context)
                : base(context)
            {
                print("myChannelFactory(xontext)");
            }
    
            protected override TChannel OnCreateChannel(EndpointAddress address, Uri via)
            {
                print("OnCreateChannel(address,via)");
                IRequestChannel requestchannel = (IRequestChannel)InnerFactory.CreateChannel(address, via);
                    return (TChannel)(object)new myRequestChannel(this,requestchannel);
            }
    
        }
    View Code

    六、自定义绑定元素
      myBindingElement继承BindingElement基类,通过BuildChannelFactory、BuildChannelListener方法创建myChannelFactory、BuildChannelListener

     class myBindingElement:BindingElement
        {
            protected void print(string methodname)
            {
                Console.WriteLine("{0}:{1}", this.GetType().Name, methodname);
            }
            public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
            {
                print("BuildChannelFactory<TChannel>(BindingContext context)");
                return new myChannelFactory<TChannel>(context);
            }
    
            public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context) 
            { 
                print("IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context) where TChannel : class, IChannel");
                return new myChannelListener<TChannel>(context);
            }
            public override BindingElement Clone()
            {
                return new myBindingElement();
            }
    
            public override T GetProperty<T>(BindingContext context)
            {
                return context.GetInnerProperty<T>();
            }
        }
    View Code

    七、自定义绑定

      经过前面一系列创建,接下来放大招了。myBinding,把自定义绑定元素放在绑定元素集合中的第一个位置。当服务端执行的时候,我们自定义的绑定元素啥都不干,直接调用下一个绑定元素的种种通信对象干活。

     public class myBinding:Binding
        {
            private BindingElement[] binds = new BindingElement[]
            {
              new myBindingElement(),
              new TextMessageEncodingBindingElement(),
              new HttpTransportBindingElement()
            };
    
            private HttpTransportBindingElement transportbind;
    
            public override BindingElementCollection CreateBindingElements()
            {
                transportbind = (HttpTransportBindingElement)binds[2];
                return new BindingElementCollection(binds);
            }
    
            public override string Scheme
            {
                get { return transportbind.Scheme; }
            }
        }
    View Code

    八、服务端使用自定义自定义绑定

     static void Main(string[] args)
            {
                using (ServiceHost host = new ServiceHost(typeof(mywcf.Calculator)))
                {
                    host.AddServiceEndpoint(typeof(mywcf.ICalculator), new myBinding(), "http://localhost:4216");
                    host.Opened += delegate { Console.WriteLine("Service Start!"); };
                    host.Open();
                    Console.ReadLine();
                }
            }
    View Code

    运行一下,控制台输出,可以看到运行步骤。先创建了信道监听器、Open、再创建自定义信道、接着Open、然后进入接受消息状态。这个和前一篇博文代码顺序一致。

    九、客户端代码

     static void Main(string[] args)
            {
                ChannelFactory<mywcf.ICalculator> factory = new ChannelFactory<mywcf.ICalculator>(new myBinding(), new EndpointAddress("http://localhost:4216"));
                mywcf.ICalculator client = factory.CreateChannel();
                Console.WriteLine(client.Add(1, 2));
            }
    View Code

    运行客户端输出,创建信道工厂、Open、创建请求信道、Open、Request发送请求。与前一章客户端代码运行顺序一致。

  • 相关阅读:
    列表 list
    flask实现json数据处理、学生信息表格展示和jinjia2的用法
    flask实现用户登录和上传文件
    移动端APP测试
    charles-截取移动端请求-设置代理
    charles-过滤网络请求方法
    badboy的录制和jmeter的使用
    jmeter之关联
    jmeter集合点
    jmeter之检查点
  • 原文地址:https://www.cnblogs.com/lh218/p/4394841.html
Copyright © 2020-2023  润新知