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);
        }
    }

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; }
        }
    }

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);
        }
    }

四、自定义信道监听器
 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);
        }
    }

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;
        }

    }

五、自定信道工厂

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);
        }
    }

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);
        }

    }

六、自定义绑定元素
  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>();
        }
    }

七、自定义绑定

经过前面一系列创建,接下来放大招了。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; }
        }
    }

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

 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();
            }
        }

运行一下,控制台输出,可以看到运行步骤。先创建了信道监听器、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));
        }

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

时间: 2024-10-24 22:47:26

WCF-绑定模型(二)的相关文章

Android基于ksoap2调用WCF服务(二):Android篇

上一篇通过一个非常简单的例子,完成了一个WCF的服务.接下来介绍一下Android端. Android端调用WCF,采用基于ksoap2包来实现. 下载地址(这个需要fan qiang访问,你们懂的):https://code.google.com/p/ksoap2-android/ 我用的3.3.0版本,我传到csdn上,上面地址如果不能访问,可以用这个地址:http://download.csdn.net/detail/cnryc/7695437 程序的源代码下载地址:http://down

WCF绑定和行为在普通应用和SilverLight应用一些对比

本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 阅读目录 介绍 绑定 行为 普通应用和SilverLight应用区别 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 介绍 WCF是构建和运行互联系统的一系列技术的总称,它是建立在Web Service架构上的一个全新的通信平台.我们可以把它看成是.NET平台上的新一代的Web Service.WCF的绑定和行为可以对提供的服务提供不同的通信方式支持和其

201507221403_《backbone之一——新建模型和集合、实例化模型、模型上监听事件的方法、模型设置和获取后台数据、配置理由方法、视图绑定事件的方法、绑定模型等》

一 . 新建 var model_1 = new Backbone.Model({'name':'hello'}); var model_2 = new Backbone.Model({'name':'hi'}); var models = new Backbone.Collection(); models.add( model_1 ); models.add( model_2 ); alert( JSON.stringify(models) ); 二. 实例化模型 var M = Backbo

WCF 通道模型——实例篇

昨天在园子里看了一位高手的文章,对于WCF通道模型从设计层面到实际运用层面讲的非常的清楚和透彻,所以今天自己也动手写一点code来理解一下. 之前关于wcf通道模型的讲解的书看了两遍也没这次理解那么的深刻. 今天演示的只是一个简单的Demo, 这个程序的code其实在MSDN上就可以找到,稍加些自己的设计在里面就可以了,但WCF底层通信的逻辑和用法与MSDN上面的演示程序是一样.接下来先介绍一下整体需求. 需求:实现一个客户端和服务端,采用Http协议和请求响应式通信方式,实现简单的文本信息发送

asp.netMVC中的自动绑定模型测试小结

很久没有自己测试测试一些东西了,今天特意测试了一下MVC中自动绑定模型.本人也是小菜,希望能帮助到小小菜....嘿嘿 1.首先,创建一个MVC4的项目 2.创建一个Controller(控制器),有些小小菜肯定也知道Home是路由里默认的. 3.控制器都有了,默认会有个Index动作方法,我们只需要在拷贝一个接受Post请求的action即可 public ActionResult Index() { return View(); } [HttpPost] //视图中加的是实体类中的属性名对应

自己写的javascript绑定模型 基于jquery

//绑定模型 $.bind = {}; //绑定基础 $.bind.base = function (get, set) { return function (o) { if (typeof (o) != 'undefined') { set(o); }; return get(); }; }; //绑定文本 $.bind.text = function (element,func) { var $el = element; return $.bind.base(function () { re

转载——Java与WCF交互(二):WCF客户端调用Java Web Service

在上篇< Java与WCF交互(一):Java客户端调用WCF服务>中,我介绍了自己如何使用axis2生成java客户端的悲惨经历.有同学问起使用什么协议,经初步验证,发现只有wsHttpBinding可行,而NetTcpBinding不可行,具体原因待查.昨晚回去重新测试WCF客户端调用Java Web Service,并将过程公布如下: 其实本不需要做web service,只是原来公开的经典的Web service像(http://soapinterop.java.sun.com/rou

WCF绑定netTcpBinding寄宿到IIS

继续沿用上一篇随笔中WCF服务类库 Wettery.WcfContract.Services WCF绑定netTcpBinding寄宿到控制台应用程序 服务端 添加WCF服务应用程序 Wettery.WcfIISHost.Services,其中添加两个WCF服务,GameService.svc  PlayerService.svc,删掉契约接口和 .cs内嵌文件,只留下.svc文件 我们通过Autofac注入契约/服务的依赖关系,Nuget引用 Install-Package Autofac.W

WCF绑定类型选择

WCF绑定类型选择   发布日期:2010年12月10日星期五 作者:EricHu   在开发WCF程序时,如何选择一个适合的绑定对于消息传输的可靠性,传输模式是否跨进程.主机.网络,传输模式的支持.安全性.性能等方面有着重要的影响.而从本质上来看,绑定具有的这些特性源于其使用的网络协议和编码器.绑定是一个定制好的通道栈,包含了协议通道.传输通道和编码器.我们在开发WCF程序时,选择合适定是一个复杂的过程,没有万能的挑选公式可以套用.但是通常地,可以从是否需要交互特性.是否跨主机.是否需要脱机交