在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. kubestack 源码分析

    简介:KubeStack is an OpenStack network provider for kubernetes.KubeStack is devided into two functions ...

  2. Keras网络层之“关于Keras的层(Layer)”

    关于Keras的“层”(Layer) 所有的Keras层对象都有如下方法: layer.get_weights():返回层的权重(numpy array) layer.set_weights(weig ...

  3. 如何根据一些参数,自动生成一个简单的maven工程,然后导入Eclipse直接使用?(maven命令)

    1. 使用mvn archetype:generate命令 2. 选择archetype类型:(默认是org.apache.maven.archetypes:maven-archetype-quick ...

  4. HTML 2 (Day49)

    一.table标签 http://www.cnblogs.com/shaojiafeng/p/7516741.html 二.form 表单属性 action:表单提交到哪.一般指向服务端一个程序,程序 ...

  5. python全栈开发从入门到放弃之列表的内置方法

    1.列表切片 l=['a','b','c','d','e','f'] print(l[1:5]) # 根据索引号来切片,但顾头不顾尾 ['b', 'c', 'd', 'e'] print(l[1:5: ...

  6. dymaic方式的Json序列化

    from:http://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object If you ...

  7. JSP SERVLET 基础知识

    jsp(java server page)和servlet是JAVA EE规范的两个基本成员,是JAVA WEB开发的重点也是基础知识.JSP本质上也需要编译成SERVLET运行. JSP比较简单,可 ...

  8. iOS 多线程安全 与可变数组

    完全来自于iOS 多线程安全与可变字典 的学习 基本相同,举一反三 直接上样例代码 是我参照网上,根据当前业务需求改的. 其实好多人在这里喜欢用类别处理.我个人觉得用类别 极其容易和普通方法混淆,所以 ...

  9. MongoRepository动态代理及jpa方法解析源码分析

    public interface FzkRepository extends MongoRepository<Fzk, String> { Fzk findByName(String na ...

  10. Linux——网络配置及命令

    traceroute命令(unix)/tracert命令(windows) tracert命令的格式为:tracert [-d] [-h maximum_hops] [-j host-list] [- ...