二、绑定元素

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

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

  1. TransactionFlowBindingElement
  2. BinaryMessageEncodingBindingElement
  3. WindowsStreamSecurityBindingElement
  4. TcpTransportBindingElement

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

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

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

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

三、创建自定义信道

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

  1. class myChannelBase:ChannelBase
  2. {
  3.  
  4. public ChannelBase InnerChannel { get; private set; }
  5. public myChannelBase(ChannelManagerBase channelManager, ChannelBase InnerChannel)
  6. : base(channelManager)
  7. {
  8. this.InnerChannel = InnerChannel;
  9. }
  10.  
  11. public override T GetProperty<T>()
  12. {
  13. print("GetProperty<T>");
  14. return InnerChannel.GetProperty<T>();
  15. }
  16.  
  17. protected void print(string methodname)
  18. {
  19. Console.WriteLine("{0}:{1}", this.GetType().Name, methodname);
  20. }
  21. protected override void OnAbort()
  22. {
  23. print("OnAbort");
  24. InnerChannel.Abort();
  25. }
  26.  
  27. protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
  28. {
  29. print("OnBeginClose");
  30. return InnerChannel.BeginClose(timeout, callback, state);
  31. }
  32.  
  33. protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
  34. {
  35. print("OnBeginOpen");
  36. return InnerChannel.BeginOpen(timeout, callback, state);
  37. }
  38.  
  39. protected override void OnClose(TimeSpan timeout)
  40. {
  41. print("OnClose");
  42. InnerChannel.Close(timeout);
  43. }
  44.  
  45. protected override void OnEndClose(IAsyncResult result)
  46. {
  47. print("OnEndClose");
  48. InnerChannel.EndClose(result);
  49. }
  50.  
  51. protected override void OnEndOpen(IAsyncResult result)
  52. {
  53. print("OnEndOpen");
  54. InnerChannel.EndOpen(result);
  55. }
  56.  
  57. protected override void OnOpen(TimeSpan timeout)
  58. {
  59. print("OnOpen");
  60. InnerChannel.Open(timeout);
  61. }
  62. }

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

  1. class myRequestChannel:myChannelBase,IRequestChannel
  2. {
  3. public IRequestChannel InnerRequestChannel
  4. {
  5. get
  6. {
  7. return (IRequestChannel)base.InnerChannel;
  8. }
  9. }
  10. public myRequestChannel(ChannelManagerBase channelManager, IRequestChannel InnerRequestChannel)
  11. : base(channelManager, (ChannelBase)InnerRequestChannel)
  12. {
  13. base.print("myRequestChannel()");
  14. }
  15. public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
  16. {
  17. base.print("BeginRequest(message,timeout,callback,state)");
  18. return InnerRequestChannel.BeginRequest(message, timeout, callback, state);
  19. }
  20.  
  21. public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state)
  22. {
  23. base.print("BeginRequest(message,callback,state)");
  24. return InnerRequestChannel.BeginRequest(message, callback, state);
  25. }
  26.  
  27. public Message EndRequest(IAsyncResult result)
  28. {
  29. base.print("EndRequest(result)");
  30. return InnerRequestChannel.EndRequest(result);
  31. }
  32.  
  33. public EndpointAddress RemoteAddress
  34. {
  35. get { return InnerRequestChannel.RemoteAddress; }
  36. }
  37.  
  38. public Message Request(Message message, TimeSpan timeout)
  39. {
  40. base.print("Request(message,timeout)");
  41. return InnerRequestChannel.Request(message, timeout);
  42. }
  43.  
  44. public Message Request(Message message)
  45. {
  46. base.print("Request(message)");
  47. return InnerRequestChannel.Request(message);
  48. }
  49.  
  50. public Uri Via
  51. {
  52. get { return InnerRequestChannel.Via; }
  53. }
  54. }

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

  1. class myReplyChannel:myChannelBase,IReplyChannel
  2. {
  3. public IReplyChannel InnerRepleyChannel
  4. {
  5. get
  6. {
  7. return (IReplyChannel)base.InnerChannel;
  8. }
  9. }
  10. public myReplyChannel(ChannelManagerBase channelManager, IReplyChannel InnerRepleyChannel)
  11. : base(channelManager, (ChannelBase)InnerRepleyChannel)
  12. {
  13. base.print("myReplyChannel()");
  14. }
  15.  
  16. public IAsyncResult BeginReceiveRequest(TimeSpan timeout, AsyncCallback callback, object state)
  17. {
  18. base.print("BeginReceiveRequest(timeout, callback, state)");
  19. return InnerRepleyChannel.BeginReceiveRequest(timeout, callback, state);
  20. }
  21.  
  22. public IAsyncResult BeginReceiveRequest(AsyncCallback callback, object state)
  23. {
  24. base.print("BeginReceiveRequest(callback, state)");
  25. return InnerRepleyChannel.BeginReceiveRequest(callback, state);
  26. }
  27.  
  28. public IAsyncResult BeginTryReceiveRequest(TimeSpan timeout, AsyncCallback callback, object state)
  29. {
  30. base.print("BeginTryReceiveRequest(timeout,callback, state)");
  31. return InnerRepleyChannel.BeginTryReceiveRequest(timeout,callback, state);
  32. }
  33.  
  34. public IAsyncResult BeginWaitForRequest(TimeSpan timeout, AsyncCallback callback, object state)
  35. {
  36. base.print("BeginWaitForRequest(timeout,callback, state)");
  37. return InnerRepleyChannel.BeginWaitForRequest(timeout, callback, state);
  38. }
  39.  
  40. public RequestContext EndReceiveRequest(IAsyncResult result)
  41. {
  42. base.print("EndReceiveRequest(result)");
  43. return InnerRepleyChannel.EndReceiveRequest(result);
  44. }
  45.  
  46. public bool EndTryReceiveRequest(IAsyncResult result, out RequestContext context)
  47. {
  48. base.print("EndTryReceiveRequest(result,out context)");
  49. return InnerRepleyChannel.EndTryReceiveRequest(result, out context);
  50. }
  51.  
  52. public bool EndWaitForRequest(IAsyncResult result)
  53. {
  54. base.print("EndWaitForRequest(result)");
  55. return InnerRepleyChannel.EndWaitForRequest(result);
  56. }
  57.  
  58. public EndpointAddress LocalAddress
  59. {
  60. get { return InnerRepleyChannel.LocalAddress; }
  61. }
  62.  
  63. public RequestContext ReceiveRequest(TimeSpan timeout)
  64. {
  65. base.print("ReceiveRequest(timeout)");
  66. return InnerRepleyChannel.ReceiveRequest(timeout);
  67. }
  68.  
  69. public RequestContext ReceiveRequest()
  70. {
  71. base.print("ReceiveRequest()");
  72. return InnerRepleyChannel.ReceiveRequest();
  73. }
  74.  
  75. public bool TryReceiveRequest(TimeSpan timeout, out RequestContext context)
  76. {
  77. base.print("TryReceiveRequest(timeout,out context)");
  78. return InnerRepleyChannel.TryReceiveRequest(timeout, out context);
  79. }
  80.  
  81. public bool WaitForRequest(TimeSpan timeout)
  82. {
  83. base.print("WaitForRequest(timeout)");
  84. return InnerRepleyChannel.WaitForRequest(timeout);
  85. }
  86. }

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

  1. class myChannelListenerBase<TChannel> : ChannelListenerBase<TChannel> where TChannel : class,IChannel
  2. {
  3. public IChannelListener<TChannel> InnreListener
  4. {
  5. get;
  6. private set;
  7. }
  8. public myChannelListenerBase(BindingContext context)
  9. {
  10. InnreListener = context.BuildInnerChannelListener<TChannel>();
  11. }
  12.  
  13. protected void print(string methodname)
  14. {
  15. Console.WriteLine("{0}:{1}", this.GetType().Name, methodname);
  16. }
  17.  
  18. protected override TChannel OnAcceptChannel(TimeSpan timeout)
  19. {
  20. print("OnAcceptChannel(timeout)");
  21. return InnreListener.AcceptChannel(timeout);
  22. }
  23.  
  24. protected override IAsyncResult OnBeginAcceptChannel(TimeSpan timeout, AsyncCallback callback, object state)
  25. {
  26. print("OnBeginAcceptChannel(timeout,callback,state)");
  27. return InnreListener.BeginAcceptChannel(timeout, callback, state);
  28. }
  29.  
  30. protected override TChannel OnEndAcceptChannel(IAsyncResult result)
  31. {
  32. print("OnEndAcceptChannel(result)");
  33. return InnreListener.EndAcceptChannel(result);
  34. }
  35.  
  36. protected override IAsyncResult OnBeginWaitForChannel(TimeSpan timeout, AsyncCallback callback, object state)
  37. {
  38. print("OnBeginWaitForChannel(timeout,callback,state)");
  39. return InnreListener.BeginWaitForChannel(timeout, callback, state);
  40. }
  41.  
  42. protected override bool OnEndWaitForChannel(IAsyncResult result)
  43. {
  44. print("OnEndWaitForChannel(result)");
  45. return InnreListener.EndWaitForChannel(result);
  46. }
  47.  
  48. protected override bool OnWaitForChannel(TimeSpan timeout)
  49. {
  50. print("OnWaitForChannel(timeout)");
  51. return InnreListener.WaitForChannel(timeout);
  52. }
  53.  
  54. public override Uri Uri
  55. {
  56. get { return InnreListener.Uri; }
  57. }
  58.  
  59. protected override void OnAbort()
  60. {
  61. print("OnAbort()");
  62. InnreListener.Abort();
  63. }
  64.  
  65. protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
  66. {
  67. print("OnBeginClose(timeout,callback,state)");
  68. return InnreListener.BeginClose(timeout, callback, state);
  69. }
  70.  
  71. protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
  72. {
  73. print("OnBeginOpen(timeout,callback,state)");
  74. return InnreListener.BeginOpen(timeout, callback, state);
  75. }
  76.  
  77. protected override void OnClose(TimeSpan timeout)
  78. {
  79. print("OnClose(timeout)");
  80. InnreListener.Close(timeout);
  81. }
  82.  
  83. protected override void OnEndClose(IAsyncResult result)
  84. {
  85. print("OnEndClose(result)");
  86. InnreListener.EndClose(result);
  87. }
  88.  
  89. protected override void OnEndOpen(IAsyncResult result)
  90. {
  91. print("OnEndOpen(result)");
  92. InnreListener.EndOpen(result);
  93. }
  94.  
  95. protected override void OnOpen(TimeSpan timeout)
  96. {
  97. print("OnOpen(timeout)");
  98. InnreListener.Open(timeout);
  99. }
  100. }

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

  1. class myChannelListener<TChannel> : myChannelListenerBase<TChannel> where TChannel : class,IChannel
  2. {
  3.  
  4. public myChannelListener(BindingContext context)
  5. : base(context)
  6. {
  7. }
  8.  
  9. protected override TChannel OnAcceptChannel(TimeSpan timeout)
  10. {
  11. print("OnAcceptChannel(timeout)");
  12. IReplyChannel replyCHannel = (IReplyChannel)InnreListener.AcceptChannel(timeout);
  13. return (new myReplyChannel(this, replyCHannel) as TChannel);
  14. }
  15.  
  16. protected override TChannel OnEndAcceptChannel(IAsyncResult result)
  17. {
  18. print("OnEndAcceptChannel(result)");
  19. IReplyChannel replychannel= InnreListener.EndAcceptChannel(result) as IReplyChannel;
  20. return new myReplyChannel(this, replychannel) as TChannel;
  21. }
  22.  
  23. }

五、自定信道工厂

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

  1. class myChannelFactoryBase<TChannel> : ChannelFactoryBase<TChannel>
  2. {
  3. public IChannelFactory<TChannel> InnerFactory
  4. {
  5. get;
  6. private set;
  7. }
  8.  
  9. protected void print(string methodname)
  10. {
  11. Console.WriteLine("{0}:{1}", this.GetType().Name, methodname);
  12. }
  13. public myChannelFactoryBase(BindingContext context)
  14. {
  15. print("myChannelFactoryBase(context)");
  16. InnerFactory= context.BuildInnerChannelFactory<TChannel>();
  17. }
  18.  
  19. protected override TChannel OnCreateChannel(EndpointAddress address, Uri via)
  20. {
  21. print("OnCreateChannel(address,via)");
  22. return InnerFactory.CreateChannel(address,via);
  23. }
  24.  
  25. protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
  26. {
  27. print("OnBeginOpen(timeout,callback,state)");
  28. return InnerFactory.BeginOpen(timeout, callback, state);
  29. }
  30.  
  31. protected override void OnEndOpen(IAsyncResult result)
  32. {
  33. print("OnEndOpen(result)");
  34. InnerFactory.EndOpen(result);
  35. }
  36.  
  37. protected override void OnOpen(TimeSpan timeout)
  38. {
  39. print("OnOpen(timeout)");
  40. InnerFactory.Open(timeout);
  41. }
  42. }

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

  1. class myChannelFactory<TChannel> : myChannelFactoryBase<TChannel>
  2. {
  3.  
  4. public myChannelFactory(BindingContext context)
  5. : base(context)
  6. {
  7. print("myChannelFactory(xontext)");
  8. }
  9.  
  10. protected override TChannel OnCreateChannel(EndpointAddress address, Uri via)
  11. {
  12. print("OnCreateChannel(address,via)");
  13. IRequestChannel requestchannel = (IRequestChannel)InnerFactory.CreateChannel(address, via);
  14. return (TChannel)(object)new myRequestChannel(this,requestchannel);
  15. }
  16.  
  17. }

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

  1. class myBindingElement:BindingElement
  2. {
  3. protected void print(string methodname)
  4. {
  5. Console.WriteLine("{0}:{1}", this.GetType().Name, methodname);
  6. }
  7. public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
  8. {
  9. print("BuildChannelFactory<TChannel>(BindingContext context)");
  10. return new myChannelFactory<TChannel>(context);
  11. }
  12.  
  13. public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
  14. {
  15. print("IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context) where TChannel : class, IChannel");
  16. return new myChannelListener<TChannel>(context);
  17. }
  18. public override BindingElement Clone()
  19. {
  20. return new myBindingElement();
  21. }
  22.  
  23. public override T GetProperty<T>(BindingContext context)
  24. {
  25. return context.GetInnerProperty<T>();
  26. }
  27. }

七、自定义绑定

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

  1. public class myBinding:Binding
  2. {
  3. private BindingElement[] binds = new BindingElement[]
  4. {
  5. new myBindingElement(),
  6. new TextMessageEncodingBindingElement(),
  7. new HttpTransportBindingElement()
  8. };
  9.  
  10. private HttpTransportBindingElement transportbind;
  11.  
  12. public override BindingElementCollection CreateBindingElements()
  13. {
  14. transportbind = (HttpTransportBindingElement)binds[];
  15. return new BindingElementCollection(binds);
  16. }
  17.  
  18. public override string Scheme
  19. {
  20. get { return transportbind.Scheme; }
  21. }
  22. }

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

  1. static void Main(string[] args)
  2. {
  3. using (ServiceHost host = new ServiceHost(typeof(mywcf.Calculator)))
  4. {
  5. host.AddServiceEndpoint(typeof(mywcf.ICalculator), new myBinding(), "http://localhost:4216");
  6. host.Opened += delegate { Console.WriteLine("Service Start!"); };
  7. host.Open();
  8. Console.ReadLine();
  9. }
  10. }

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

九、客户端代码

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

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

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

  1. WCF学习之旅——第一个WCF示例(二)

    第四步:通过自我寄宿的方式寄宿服务 WCF服务需要依存一个运行着的进程(宿主),服务寄宿就是为服务指定一个宿主的过程.WCF是一个基于消息的通信框架,采用基于终结点(Endpoint)的通信手段. 终 ...

  2. WCF编程系列(二)了解WCF

    WCF编程系列(二)了解WCF   面向服务     服务是复用进化的结果,起初的复用是函数,面向对象编程的出现使复用从函数上升到对象,随后面向组件编程又将复用从对象上升到组件,现在面向服务编程将复用 ...

  3. {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询

    Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...

  4. WCF入门教程(四)通过Host代码方式来承载服务 一个WCF使用TCP协议进行通协的例子 jquery ajax调用WCF,采用System.ServiceModel.WebHttpBinding System.ServiceModel.WSHttpBinding协议 学习WCF笔记之二 无废话WCF入门教程一[什么是WCF]

    WCF入门教程(四)通过Host代码方式来承载服务 Posted on 2014-05-15 13:03 停留的风 阅读(7681) 评论(0) 编辑 收藏 WCF入门教程(四)通过Host代码方式来 ...

  5. CPF 入门教程 - 数据绑定和命令绑定(二)

    CPF netcore跨平台UI框架 系列教程 CPF 入门教程(一) CPF 入门教程 - 数据绑定和命令绑定(二) 数据绑定和Wpf类似,支持双向绑定.数据绑定和命令绑定是UI和业务逻辑分离的基础 ...

  6. WCF绑定类型选择

    WCF绑定类型选择   发布日期:2010年12月10日星期五 作者:EricHu   在开发WCF程序时,如何选择一个适合的绑定对于消息传输的可靠性,传输模式是否跨进程.主机.网络,传输模式的支持. ...

  7. django模型二

    django模型二 常用模型字段类型 IntegerField   →    int CharField   →   varchar TextField  →    longtext DateFiel ...

  8. WCF绑定netTcpBinding寄宿到IIS

    继续沿用上一篇随笔中WCF服务类库 Wettery.WcfContract.Services WCF绑定netTcpBinding寄宿到控制台应用程序 服务端 添加WCF服务应用程序 Wettery. ...

  9. [Beego模型] 二、CRUD 操作

    [Beego模型] 一.ORM 使用方法 [Beego模型] 二.CRUD 操作 [Beego模型] 三.高级查询 [Beego模型] 四.使用SQL语句进行查询 [Beego模型] 五.构造查询 [ ...

随机推荐

  1. RoadFlow ASP.NET Core工作流引擎IIS部署

    RoadFlow最新版本采用ASP.NET CORE2.1开发,部署步骤和.NET CORE部署一样,具体可参数ASP.NET CORE的部署方式. 1. 获取代码 首先从RoadFlow官网下载最新 ...

  2. NPOI 设置excel 边框

    https://blog.csdn.net/xxs77ch/article/details/50232343

  3. 实验了一下LitSphere做车漆

    前阵子跟人聊天,聊起过去试验的车漆,不适合做到移动设备上.过去试验的车漆在此http://www.cnblogs.com/sitt/archive/2012/03/28/2420595.html 于是 ...

  4. API Test Postman接口测试之高级篇2

    API Test  Postman接口测试之高级篇2 一.继承父类的设置: 二.导出及导入: 三.分享文档: 四.发布接口文档: 五.常用脚本: 右边框选的是一些常用的脚本,postman提供的,可以 ...

  5. uploadPreview 上传图片前预览 IE9 索引无效的问题

    最近公司的项目用到比较多的上传图片的操作,所以用到了基于jquery的上传前预览的插件 uploadPreview ,后来测试的时候发现在IE9下报索引无效的问题. 异常的产生方式 放一个file控件 ...

  6. 【OCP-12c】2019年CUUG OCP 071考试题库(74题)

    74.View the exhibit and examine the structure of ORDERS and CUSTOMERS tables. ORDERS Name     Null?  ...

  7. Mybatis 优化:

    Mybatis 的优化: ** 第一个 对于数据库配置的优化: 创建一个 DB.properties 的文件 里面编写Key = value 形式的数据库信息 比如: driver = com.mys ...

  8. 常见的HTTP请求应答返回码列表

        200      OK 请求成功.一般用于GET与POST请求 300 Multiple Choices 多种选择.请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例 ...

  9. [AS3.0] 解决Number类型计算不精确问题

    看下面代码运行结果: trace(256.08+123.1); //379.17999999999995 trace(256.08-123.11); //132.96999999999997 trac ...

  10. [Objective-C语言教程]扩展(30)

    类扩展与类别有一些相似之处,但它只能添加到编译时具有源代码的类中(类与类扩展同时编译). 类扩展声明的方法是在原始类的实现块中实现的,因此不能在框架类上声明类扩展,例如Cocoa或Cocoa Touc ...