在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. rem根元素的定义规则

    <script> !function(a) { function b() { var b = g.getBoundingClientRect().width; var winpix=1; ...

  2. s5_day2作业

    # 1:编写for循环,利用索引遍历出每一个字符 # msg = 'hello egon 666' # for i in range(len(msg)): # print(i,msg[i]) # 2: ...

  3. Canvas:技术小结

    Canvas:技术小结 资料 [教程:MDN官方中文教程] https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial [ ...

  4. Python 字符串连接问题归结

    一.概述 Python 字符串连接场景较为普遍.由于编者对 Java 等语言较为熟悉,常常将两者语法混淆. 加之,Python 语法较为灵活.例如,单单实现字符串连接,就有数种方法.在此,一并归结! ...

  5. CodeForces - 894E Ralph and Mushrooms (强连通缩点+dp)

    题意:一张有向图,每条边上都有wi个蘑菇,第i次经过这条边能够采到w-(i-1)*i/2个蘑菇,直到它为0.问最多能在这张图上采多少个蘑菇. 分析:在一个强连通分量内,边可以无限次地走直到该连通块内蘑 ...

  6. POJ - 1904 King's Quest (强连通)

    题意:有N个王子,每个王子有任意个喜欢的妹子,巫师会给出一个方案:每个妹子都嫁给一个王子.但是国王希望知道:每个王子能在哪些妹子中择偶而不影响其他王子择偶. 分析:设王子为x部,妹子为y部,假设有匹配 ...

  7. Openstack之Nova创建虚机流程分析

    前言        Openstack作为一个虚拟机管理平台,核心功能自然是虚拟机的生命周期的管理,而负责虚机管理的模块就是Nova. 本文就是openstack中Nova模块的分析,所以本文重点是以 ...

  8. 20145109 《Java程序设计》第六周学习总结

    Chapter 10 I/O 10.1 InputStream & OutputStream a new 'try' edition: try (InputStream input = src ...

  9. tinyxml优化之二

    原文链接:http://www.cnblogs.com/zouzf/p/4216046.html tinyxml优化之一说到了效率在差别有三方面的原因:解析的方式.内存分配(字符串操作).冗余的安全性 ...

  10. 使用Kali Linux 破解无线网

    用到的工具 airmon-ngairodump-ngaireplay-ngaircrack-ng 过程 123456789101112131415161718192021222324 root@lm: ...