在WCF绑定体系中,绑定创建绑定元素,绑定元素创建绑定监听器/绑定工厂,绑定监听器/绑定工厂创建信道。

WCF中绑定是有多个信道相连组成的信道栈,在这个信道栈中必须包含传输信道和编码信道,而且传输信道必须在栈底,在信道栈里面可以添加自定义的信道或是一些协议信道(WS-*标准),在这些协议信道中可以一些消息的处理,比如事务的流转,保证消息的安全传输等。在WCF的信道栈中每一个信道都对信道有这单一的处理功能,多个信道组成的信道栈就可以处理多种功能的消息;

Binding

public abstract class Binding : IDefaultCommunicationTimeouts
{
public virtual IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingParameterCollection parameters) where TChannel : class, IChannel;
public abstract BindingElementCollection CreateBindingElements();
public virtual bool CanBuildChannelListener<TChannel>(BindingParameterCollection parameters) where TChannel : class, IChannel;
}

在Binding 类中通过调用BuildChannelListener<TChannel>方法来创建信道监听器;CreateBindingElements()方法时创建绑定元素集合,因为绑定元素创建信道监听器,因此绑定集合也就构成了一个信道的列表;

在WCF的系统绑定中的支持TCP/IP的的NetTcpBinding,它内部实现CreateBindingElements方法:

public class NetTcpBinding : Binding
{
private void Initialize()
{
this.transport = new TcpTransportBindingElement();
this.encoding = new BinaryMessageEncodingBindingElement();
this.context = GetDefaultTransactionFlowBindingElement();
this.session = new ReliableSessionBindingElement();
this.reliableSession = new OptionalReliableSession(this.session);
}

private static TransactionFlowBindingElement GetDefaultTransactionFlowBindingElement()
    {
     return new TransactionFlowBindingElement(false);
    }

   public override BindingElementCollection CreateBindingElements()
{
this.CheckSettings();
BindingElementCollection elements = new BindingElementCollection();
elements.Add(this.context);
if (this.reliableSession.Enabled)
{
elements.Add(this.session);
}
SecurityBindingElement item = this.CreateMessageSecurity();
if (item != null)
{
elements.Add(item);
}
elements.Add(this.encoding);
BindingElement element2 = this.CreateTransportSecurity();
if (element2 != null)
{
elements.Add(element2);
}
this.transport.ExtendedProtectionPolicy = this.security.Transport.ExtendedProtectionPolicy;
elements.Add(this.transport);
return elements.Clone();
}
}

在NetTcpBinding中的CreateBindingElements方法

1.创建绑定元素集合(BindingElementCollection)并在集合中添加对绑定的事务流支持的绑定元素(TransactionFlowBindingElement);

2.当前绑定启用可靠会话传输,则在绑定集合中添加支持可生成终结点间可靠会话所需的发送和接收通道的绑定元素(ReliableSessionBindingElement);

3.根据绑定的安全设置来生成支持通道 SOAP 消息安全的绑定元素(SecurityBindingElement)添加到绑定元素集合中;

4.在绑定元素集合中添加必需的消息编码绑定元素,由于Tcp采用二进制传输,因此创建支持而二进制编码的编码绑定元素(BinaryMessageEncodingBindingElement);

5.如果绑定的安全设置为使用安全传输(例如 HTTPS)提供安全性(SecurityMode.Transport/SecurityMode.TransportWithMessageCredential)或则创建保证传输保证和认证的绑定元素(WindowsStreamSecurityBindingElement,SslStreamSecurityBindingElement)

6.在绑定元素集合的最后添加支持传输的传输绑定元素(TcpTransportBindingElement),保证传输信道在栈底;

通过CreateBindingElements方法就为一个绑定创建了一个多个绑定元素集合,在创建信道监听器或是信道工厂时就是通过这个绑定元素集合进行创建;

public abstract class Binding : IDefaultCommunicationTimeouts
{ public virtual IChannelListener<TChannel> BuildChannelListener<TChannel>(Uri listenUriBaseAddress, string listenUriRelativeAddress, ListenUriMode listenUriMode, BindingParameterCollection parameters) where TChannel: class, IChannel
{
this.EnsureInvariants();
BindingContext context = new BindingContext(new CustomBinding(this), parameters, listenUriBaseAddress, listenUriRelativeAddress, listenUriMode);
IChannelListener<TChannel> listener = context.BuildInnerChannelListener<TChannel>();
context.ValidateBindingElementsConsumed();
this.ValidateSecurityCapabilities(listener.GetProperty<ISecurityCapabilities>(), parameters);
return listener;
}
}

在Binding 类中的BuildChannelListener方法中首先会调用EnsureInvariants方法,其实内部就是调用CreateBindingElements集合,然后创建绑定上下文(BindingContext)对象,通过绑定上下文的 BuildInnerChannelListener方法来创建信道监听器;

BindingContext

public class BindingContext
{
private CustomBinding binding;
private BindingParameterCollection bindingParameters;
private Uri listenUriBaseAddress;
private System.ServiceModel.Description.ListenUriMode listenUriMode;
private BindingElementCollection remainingBindingElements;
public IChannelListener<TChannel> BuildInnerChannelListener<TChannel>() where TChannel: class, IChannel
{
return this.RemoveNextElement().BuildChannelListener<TChannel>(this);
} private BindingElement RemoveNextElement()
{
BindingElement element = this.remainingBindingElements.Remove<BindingElement>();
if (element == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.ServiceModel.SR.GetString("NoChannelBuilderAvailable", new object[] { this.binding.Name, this.binding.Namespace })));
}
return element;
}
}

在绑定上文类中CustomBinding 表示创建绑定上下文的绑定对象,而BindingElementCollection表示绑定对象的绑定元素的上下文集合;

当调用BuildInnerChannelListener创建信道监听器时,首先取出BindingElementCollection元素中的一个绑定元素,并将该绑定元素从BindingElementCollection集合中移除,调用BindingElement的BuildChannelListener的方法来创建绑定监视器,而在BindingElement执行BuildChannelListener方法时又会调用绑定上下文的BuildInnerChannelListener方法,由于BindingElementCollection集合是动态变化的,因此每次都会取集合的第一元素来创建,并移除第一个绑定元素,当所有的绑定元素都调用完毕后,就创建了按照绑定元素集合顺序组成的信道栈;

WCF基础:绑定(三)的更多相关文章

  1. WCF基础:绑定(一)

    WCF中的终结点(ServiceEndpoint)包含有三要素:地址(EndpointAddress),绑定(Binding),契约描述(ContractDescription)三要素:其中绑定的在整 ...

  2. WCF基础:绑定(二)

    在WCF的绑定体系中,经常会碰到ICommunicationObject接口,无论是IChannel接口还是IChannelListener/IChannelFactory接口都继承了ICommuni ...

  3. WCF编程系列(三)地址与绑定

    WCF编程系列(三)地址与绑定   地址     地址指定了接收消息的位置,WCF中地址以统一资源标识符(URI)的形式指定.URI由通讯协议和位置路径两部分组成,如示例一中的: http://loc ...

  4. WCF服务编程 读书笔记——第1章 WCF基础(2)

    续:第1章 WCF基础(1) 元数据交换 服务有两种方案可以发布自己的元数据.一种是基于HTTP-GET协议提供元数据, 另一种则是后面将要讨论的使用专门的终结点的方式.WCF能够为服务自动提供基于H ...

  5. WCF服务编程 读书笔记——第1章 WCF基础(1)

    第1章 WCF基础 本章主要介绍WCF的基本概念.构建模块以及WCF体系架构,以指导读者构建一个简单的WCF服务.从本章的内容中,我们可以了解到WCF的基本术语,包括地址(Address).绑定(Bi ...

  6. WCF基础之设计和实现服务协定

    本来前面还有一个章节“WCF概述”,这章都是些文字概述,就不“复制”了,直接从第二章开始. 当然学习WCF还是要些基础的.https://msdn.microsoft.com/zh-cn/hh1482 ...

  7. ASP.NET MVC Model绑定(三)

    ASP.NET MVC Model绑定(三) 前言 看过前两篇的朋友想必对Model绑定有个大概的了解,然而MVC框架给我们提供了更高的可扩展性的提供程序编程模式,也就是本篇的主题了,会讲解一下Mod ...

  8. WCF学习之旅——第一个WCF示例(三)

    第五步:创建客户端 WCF应用服务被成功寄宿后,WCF服务应用便开始了服务调用请求的监听工作.此外,服务寄宿将服务描述通过元数据的形式发布出来,相应的客户端就可以获取这些元数据.接下来我们来创建客户端 ...

  9. [WCF编程]3.WCF基础

    一.服务 服务是一组公开功能的集合. 服务内部包含了如语言.技术.版本与框架等概念,服务之间的交互只允许使用规定的通信模式 外界客户端并不知道服务内部的实现细节,所以WCF服务通常通过元数据的方式描述 ...

随机推荐

  1. CNI IPAM插件分析 --- 以hostlocal为示例

    skel.CmdArgs数据结构如下所示: type CmdArgs struct { ContainerID string Netns string IfName string Args strin ...

  2. JsonResponse对象浅析

    JsonResponse   JsonResponse 对象: class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_ ...

  3. iOS学习之数据持久化详解

    前言 持久存储是一种非易失性存储,在重启设备时也不会丢失数据.Cocoa框架提供了几种数据持久化机制: 1)属性列表: 2)对象归档: 3)iOS的嵌入式关系数据库SQLite3: 4)Core Da ...

  4. Winio.dll的使用

    Winio.dll的使用 WinIO程序库允许在32位的Windows应用程序中直接对I/O端口和物理内存进行存取操作.通过使用一种内核模式的设备驱动器和其它几种底层编程技巧,它绕过了Windows系 ...

  5. springmvc ExceptionHandler

    /** * 1. 在 @ExceptionHandler 方法的入参中可以加入 Exception 类型的参数, 该参数即对应发生的异常对象 * 2. @ExceptionHandler 方法的入参中 ...

  6. springmvc 需要用到的核心jar包

    aopbeanscontextcoreexpressionwebwebmvc

  7. 2018 Multi-University Training Contest 1 - D Distinct Values (STL+双指针)

    题意:数量为N的序列,给定M个区间,要求对每个区间Li,Ri,都有al..r (l≤i<j≤r), ai≠aj.构造这个序列使其字典序最小. 分析:如果对于每个所给区间都暴力扫一遍,1e5的数据 ...

  8. netty3---传统IO,NIO,nettyIO

    传统: NIO: nettyIO: 每个服务生负责一个区域,每个服务生是一个线程.

  9. EasyUI:年份、月份下拉框Demo

    EasyUI:年份.月份下拉框Demo jsp中定义: <td width="10%" height="25px" style="text-al ...

  10. HTML5/CSS3图片左右切换弹性动画

    在线演示 本地下载