二、绑定元素

每一个类型的绑定最重要的就是绑定元素了,每个绑定的功能特性都由绑定元素决定。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[];
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(, ));
}

运行客户端输出,创建信道工厂、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. cesium随笔 — 获取当前鼠标的经度、纬度、高度

    代码: function getPosition() { //得到当前三维场景 var scene = viewer.scene; //得到当前三维场景的椭球体 var ellipsoid = sce ...

  2. asp.net mvc全局异常捕获

    通过重写OnException方法形式实现. 1.自定义异常记录类并继承HandleErrorAttribute类. public class HandlerErrorAttribute : Hand ...

  3. Luogu1438 无聊的数列(单点查询)&&加强版(区间查询)

    题目链接:戳我 线段树中差分和前缀和的应用 其实对于加上等差数列的操作我们可以分成这样三步-- update(1,1,n,l,l,k); if(r>l) update(1,1,n,l+1,r,d ...

  4. Linux—virtualbox系统安装(1)

    安装过程 1 点击新建 2 内存大小一般512M即可 3 按照默认的硬盘空间大小8G 4 选择第一个VDI 5 选择固定大小,系统运行速度快,效率高 6 保存文件位置 7 创建成功后,点击设置,将软驱 ...

  5. Windows安装Node.js报错:2503、2502的解决方法

    以管理员身份用msiexec安装 1.以管理员身份运行cmd命令 (Win + X, A) 以管理员身份运行cmd 2.cd到自己msi路径  用msiexec安装 用msiexec安装nodejs

  6. 代码审计之Catfish CMS v4.5.7后台作者权限越权两枚+存储型XSS一枚

    首先本地搭建环境,我所使用的是Windows PHPstudy集成环境.使用起来非常方便.特别是审计的时候.可以任意切换PHP版本. 本文作者:226safe Team – Poacher 0×01 ...

  7. [Swift实际操作]七、常见概念-(14)使用UIColor设置界面组件的颜色属性

    打开移动应用程序,不可避免的需要和颜色打交道.本文将为你演示颜色对象的使用. 首先导入需要使用到的界面工具框架 import UIKit 通过UIColor的属性,可以获得橙色.右侧的实时反馈区,显示 ...

  8. CentOS6.5下samba服务

    为减少错误已提前关掉了SELinux,防火墙. 安装rpm包: samba-3.6.9-164.el6.x86_64.rpm 启动检测:samba服务可以正常启动!(证明RPM安装正常) 配置文件位置 ...

  9. 零基础学习Python数据分析

    网上虽然有很多Python学习的教程,但是大多是围绕Python网页开发等展开.数据分析所需要的Python技能和网页开发等差别非常大,本人就是浪费了很多时间来看这些博客.书籍.所以就有了本文,希望能 ...

  10. 第一个PSP0级

    1.计划: 需求描述: 按照图片要求设计添加新课程界面.(0.5分) 在后台数据库中建立相应的表结构存储课程信息.(0.5分) 实现新课程添加的功能. 要求判断任课教师为王建民.刘立嘉.刘丹.王辉.杨 ...