zoukankan      html  css  js  c++  java
  • WCF中的Binding模型之六(完结篇):从绑定元素认识系统预定义绑定

    由于绑定对象由一系列有序的绑定元素组成,绑定元素最终决定着信道栈中信道的组成,而信道的组成最终又决定了信道栈对消息进行处理的方式和能力,所有要确定绑定的特性和能力,我们可以通过查看其绑定元素的构成来一窥究竟。为此我们我们写了一个简单的方法,用于列出一个具体的绑定对象所有的绑定元素,在介绍一个个具体的系统绑定中,我会使用该方法:

       1: static void ListAllBindingElements(Binding binding)
       2: {
       3:     BindingElementCollection elements = binding.CreateBindingElements();
       4:     for (int i = 0; i < elements.Count; i++)
       5:     {
       6: Console.WriteLine("{0}. {1}", i+1, elements[i].GetType().FullName);
       7:     }
       8: }

    一、BasicHttpBinding

    我们通过调用默认的构造函数创建一个绑定对象,并借助上面的ListAllBindingElements方法列出该绑定对象所有的绑定元素:

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         BasicHttpBinding binding = new BasicHttpBinding();
       6:         ListAllBindingElements(binding);
       7:     }
       8: }

    将会得到如下的输出,从中可以看出在默认的情况下,一个BasicHttpBinding包含两个最基本的绑定元素:最为传输元素的HttpTransportBindingElement和作为消息编码元素的TextMessageEncodingBindingElement。所以BasicHttpBinding在默认的情况下采用HTTP传输协议,和基于文本的消息编码方式。之所以将此绑定命名为BasicHttpBinding,很大程度上缘于它仅仅包含一些最基本的用于消息通信的元素。

    1. System.ServiceModel.Channels.TextMessageEncodingBindingElement
    2. System.ServiceModel.Channels.HttpTransportBindingElement

    除了提供最基本的传输和编码功能外,BasicHttpBinding还提供了对安全的支持,无论是基于传输的安全还是基于消息的安全,都可以通过对绑定进行相应的设置实现。我们同样通过列出绑定元素的方式来证明这一点。下面的代码中,在创建BasicHttpBinding对象的时候,指定一个BasicHttpSecurityMode.Transport参数将安全模式设为传输安全模式:

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
       6:         ListAllBindingElements(binding);
       7:     }
       8: }

    在最终的输出中我们可以看到,传输绑定元素由HttpTransportBindingElement变成了HttpsTransportBindingElement,由此可以看出BasicHttpBinding通过HTTPS实现传输安全。

    1. System.ServiceModel.Channels.TextMessageEncodingBindingElement
    2. System.ServiceModel.Channels.HttpsTransportBindingElement

    如果我们设置成基于消息的安全模式,并将客户端的凭证类型(Client Credential Type)设为证书(Certificate,这对于基于消息安全模式的BasicHttpBinding是必须的)。

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Message);
       6:         binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.Certificate;
       7:         ListAllBindingElements(binding);
       8:     }
       9: }

    那么通过输出,我们可以看到在原有绑定元素之上,又多出了一个新的绑定元素:AsymmetricSecurityBindingElement,该元素通过非对称加密(也就是基于X509证书的加密方式)的方式实现了基于消息的安全。

    1. System.ServiceModel.Channels.AsymmetricSecurityBindingElement
    2. System.ServiceModel.Channels.TextMessageEncodingBindingElement
    3. System.ServiceModel.Channels.HttpTransportBindingElement

    对于BasicHttpBinding来说,默认采用基于文本的消息编码方式(TextMessageEncodingBindingElement),实际上BasicHttpBinding还提供对基于MTOM编码方式的支持。我们可以通过编程或者配置的方式对消息编码方式进行显式指定。在下面的代码中,通过MessageEncoding属性将编码方式指定为:WSMessageEncoding.Mtom。

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         BasicHttpBinding binding = new BasicHttpBinding();
       6:         binding.MessageEncoding = WSMessageEncoding.Mtom;
       7:         ListAllBindingElements(binding);
       8:     }
       9: }

    那么我们我们最终输出的绑定元素列表中,TextMessageEncodingBindingElement将会被实现MTOM消息编码的MtomMessageEncodingBindingElement代替。

    1. System.ServiceModel.Channels.MtomMessageEncodingBindingElement
    2. System.ServiceModel.Channels.HttpTransportBindingElement

    BasicHttpBinding是WS-BP 1.1 Spec (Basic Profile) 标准的,ASP.NET ASMX Web Service的很多标准存在于WS-BP 1.1 Spec中,比如SOAP 1.1、WSDL 1.1、Message Security 1.0等等,所以BasicHttpBinding可以和传统的ASP.NET ASMX Web Service进行互操作。

    二、 WsHttpBinding

    我们通过与BasicHttpBinding的方式来分析WsHttpBinding,先通过下面的方式列出在默认条件下(通过默认的构造函数创建WsHttpBinding对象)该绑定对象具有的所有绑定元素:

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         WsHttpBinding binding = new WsHttpBinding();
       6:         ListAllBindingElements(binding);
       7:     }
       8: }

    从下面的输出来看,从上到下一共包含4个绑定元素:TransactionFlowBindingElement、SymmetricSecurityBindingElement、TextMessageEncodingBindingElement和HttpTransportBindingElement。TransactionFlowBindingElement实现了对事物流转;SymmetricSecurityBindingElement通过对称加密的方式实现基于消息的安全;TextMessageEncodingBindingElement和HttpTransportBindingElement表明WsHttpBinding和BasicHttpBinding一样采用基于文本的编码方式和基于HTTP的传输协议。

    1. System.ServiceModel.Channels.TransactionFlowBindingElement
    2. System.ServiceModel.Channels.SymmetricSecurityBindingElement
    3. System.ServiceModel.Channels.TextMessageEncodingBindingElement
    4.System.ServiceModel.Channels.HttpTransportBindingElement

    在这了需要特别指出的就是WsHttpBinding对事务的支持。对于SOA来说,事务永远是一个重要的主题,我们不仅仅需要单方的事务支持,比如将服务端的操作纳入一个单一的事务之中,也需要事务的流转,将从客户端开始的事务自动流向服务端;不仅仅需要基于单次服务调用的事务,还需要基于多次服务访问的事务(将多次服务调用纳入同一个事务之中);不仅仅需要基于单一平台的事务支持,还需要跨平台的事务(比如将基于.NET平台的WCF服务调用和基于J2EE平台的Web服务调用纳入同一个事务中)。在WS-*体系中,WS-AT为事务定义了规范,而在WCF中,则通过TransactionFlowBindingElement实现了WS-AT规范。

    WsHttpBinding在默认的情况下就提供了对基于消息安全的支持,此外WsHttpBinding仍然提供基于HTTPS的传输安全。在下面我们对代码稍加改动,通过构造函数将WsHttpBinding设置为基于传输的安全模式:

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         WsHttpBinding binding = new WsHttpBinding(SecurityMode.Transport);
       6:         ListAllBindingElements(binding);
       7:     }
       8: }

    那么基于消息模式的SymmetricSecurityBindingElement将被去除,而作为传输绑定元素的HttpTransportBindingElement将被替换成HttpsTransportBindingElement,借此实现基于HTTPS的传输安全。

    1. System.ServiceModel.Channels.TransactionFlowBindingElement
    2. System.ServiceModel.Channels.TextMessageEncodingBindingElement
    3.System.ServiceModel.Channels.HttpsTransportBindingElement

    除了提供对传输和消息安全的支持之外,WsHttpBinding还对传输的可靠性提供支持。可靠性消息传输确保在网络环境不好的情况下消息的有效、有序抵达。WS-*通过WS-RM(Reliable Messaging)为可靠传输定义了规范,在WCF中WS-RM通过可靠会话(Reliable Session)实现了WS-RM,而WS-RM在WCF的实现通过ReliableSessionBindingElement承载。下面的代码中,我们通过另一个构造函数设定WsHttpBinding对可靠会话的支持(第二个参数代表是否支持可靠会话)。

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message, true);
       6:         ListAllBindingElements(binding);
       7:     }
       8: }

    最终的输出将包含五个绑定元素,第二个就是实现了可靠会话的ReliableSessionBindingElement。

    1.System.ServiceModel.Channels.TransactionFlowBindingElement
    2. System.ServiceModel.Channels.ReliableSessionBindingElement
    3. System.ServiceModel.Channels.SymmetricSecurityBindingElement
    4. System.ServiceModel.Channels.TextMessageEncodingBindingElement
    5.System.ServiceModel.Channels.HttpTransportBindingElement

    此外,和BasicHttpBinding一样,WsHttpBinding定义了类型为System.ServiceModel.WSMessageEncoding枚举类型的MessageEncoding属性,有两种WSMessageEncoding枚举值供你选择:Text和MTOM。

    综上所述,WsHttpBinding对大部分的WS-*提供支持,这包括我们上面提到的WS-Transactions、WS-Security、WS-Reliable Messaging等等。所以从互操作角度讲,WsHttpBinding可以和满足这些标准的Web Service进行互操作。

    三、 WsDualHttpBinding

    在前面对消息交换模式的介绍中,我们谈到三种典型的消息交换模式:单向的数据报模式、请求/回复模式和双工模式。WsDualHttpBinding就是专门为HTTP传输下双工消息交换模式设计的。

    除了基于传输的安全之外,WsHttpbing的所有的特性都被WsDualHttpBinding继承下来,这包括:基于HTTP的传输、基于文本和MTOM的消息编码、WS-Security、WS-Transactions、WS-Reliable Messaging(Reliable Session)等等。我们仍然通过输出绑定元素的方式证明这一点:

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         WSDualHttpBinding binding = new WSDualHttpBinding();
       6:         ListAllBindingElements(binding);
       7:     }
       8: }

    下面列出了输出的所有绑定元素,从中可以看出TransactionFlowBindingElement对WS-Transactions的支持;ReliableSessionBindingElement对WS-RM的支持;SymmetricSecurityBindingElement对WS-Security的支持;这些绑定元素和TextMessageEncodingBindingElement、HttpTransportBindingElement都是与WsHttpbing共有的,而CompositeDuplexBindingElement和OneWayBindingElement则是WsDualHttpBinding不具有的,这两个绑定元素实现双工通信和单项的数据报模式通信。

    1. System.ServiceModel.Channels.TransactionFlowBindingElement
    2. System.ServiceModel.Channels.ReliableSessionBindingElement
    3. System.ServiceModel.Channels.SymmetricSecurityBindingElement
    4. System.ServiceModel.Channels.CompositeDuplexBindingElement
    5. System.ServiceModel.Channels.OneWayBindingElement
    6. System.ServiceModel.Channels.TextMessageEncodingBindingElement
    7. System.ServiceModel.Channels.HttpTransportBindingElement

    对于WsHttpbing和WsDualHttpBinding的比较,还有一点值得注意的是在默认情况下,WsHttpbing并没有ReliableSessionBindingElement,也就是说在默认的情况下,WsHttpbing并不支持可靠会话,而对于基于双工通信的WsDualHttpBinding,可靠会话则是必须的。至于WsDualHttpBinding为何不支持基于传输的安全,原因也很简单,因为HTTP协议下的传输安全通过HTTPS(SSL)实现,HTTPS依赖于一个真正意义上的Web站点,也就是只有访问一个真正意义上Web站点的资源的前提下,HTTPS才会有有意义。而对于双工通信来说,由于客户端满足这样要求,所以从服务端回调客户端的传输安全是无法确保的。

    双工通信需要一个双工的通信通道,但是属性TCP/IP的读者应该很清楚,HTTP协议仅仅是一个单纯的请求/回复通信协议,也就是说基于HTTP的通信通道不可以支持双工通信,那么WsDualHttpBinding又是如果在HTTP传输协议上实现双工通信的呢?答案很简单,WsDualHttpBinding采用了两个HTTP通道。

    四、NetTcpBinding

    到此为止,我们一共介绍了三种类型的绑定。从对于传输协议的支持来看,它们都就是基于HTTP或者HTTPS的绑定;从对标准的支持看来,BasicHttpBinding提供对WS-BP 1.1的支持,WsHttpBinding和WsDualHttpBinding则对WS-*新的协议提供很好的支持,比如WS-Transactions、WS-Reliable Messaging、WS-Security等等;从消息编码的角度来看,它们均支持基于纯文本的消息编码和MTOM编码。这些属性都决定了这三种绑定具有较好的互操作性,也就是说,对于此三种绑定的应用并不限于对于基于.NET平台应用的交互,如果通过这些绑定寄宿我们的服务,其他平台的客户端可以调用我们的服务,同理我们也可以利用基于这些绑定的客户端访问其他非.NET平台的Web服务,只要对方支持相应的标准。

    接下来我们要介绍的另外三种绑定,相比之下就不具有如此好的互操作性,它们只能应用于单纯的WCF客户端和服务之间的交互。它们基于不同的传输协议,我们先来介绍基于TCP传输协议的NetTcpBinding。

    我们照例采用列出绑定元素列表的方式分析绑定的特性,我们先通过下面的代码看看一个采用默认构造函数创建的NetTcpBinding对象会包含哪些绑丁元素。

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         NetTcpBinding binding = new NetTcpBinding();
       6:         ListAllBindingElements(binding);
       7:     }
       8: }

    程序运行后,下面4个绑定元素会被先后输出。我们借来分析一个NetTcpBinding对象在默认的情况下具有哪些特性:TcpTransportBindingElement表明采用TCP作为传输协议;WindowsStreamSecurityBindingElement提供基于Windows凭证的传输安全;BinaryMessageEncodingBindingElement实现基于二进制的消息编码;TransactionFlowBindingElement则提供对事务流转的支持。

    1. System.ServiceModel.Channels.TransactionFlowBindingElement
    2. System.ServiceModel.Channels.BinaryMessageEncodingBindingElement
    3. System.ServiceModel.Channels.WindowsStreamSecurityBindingElement
    4. System.ServiceModel.Channels.TcpTransportBindingElement

    上面涉及的四个绑定元素,除了WindowsStreamSecurityBindingElement,相信有了前面的介绍,读者不会感到陌生。在这里我们来简单讨论一下WindowsStreamSecurityBindingElement。WindowsStreamSecurityBindingElement继承自System.ServiceModel.Channels.StreamUpgradeBindingElement,StreamUpgradeBindingElement是一种特殊的绑定元素。前面我们讲了,绑定元素的使命在于对相应信道的创建,而StreamUpgradeBindingElement的特别之处在于它并会参与信道的创建。StreamUpgradeBindingElement一般应用于基于流的传输(Stream Oriented Transport),比如TCP、命名管道等等。它一般位于TransportBindingElement之上,在传输层基础上提供进一步的升级处理(Transport Upgrade),比如安全加密、压缩等等。WindowsStreamSecurityBindingElement在这里的提供基于Windows客户端凭证的传输安全,与之相对的,还有一个System.ServiceModel.Channels.SslStreamSecurityBindingElement,提供基于SSL的传输安全。如果我们将绑定的客户端凭证的类型改成Certificate或者None,SslStreamSecurityBindingElement将会被采用:

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         NetTcpBinding binding = new NetTcpBinding();
       6:         binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;
       7:         ListAllBindingElements(binding);
       8:     }
       9: }

    WindowsStreamSecurityBindingElement将会被SslStreamSecurityBindingElement替换:

    1. System.ServiceModel.Channels.TransactionFlowBindingElement
    2. System.ServiceModel.Channels.BinaryMessageEncodingBindingElement
    3. System.ServiceModel.Channels.SslStreamSecurityBindingElement
    4. System.ServiceModel.Channels.TcpTransportBindingElement
     

    除了对传输安全模式的支持(默认),NetTcpBinding也提供对消息安全模式提供支持,比如下面的代码中,再调用构造函数的时候直接将安全模式类型指定为:SecurityMode.Message。

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         NetTcpBinding binding = new NetTcpBinding(SecurityMode.Message);
       6:         ListAllBindingElements(binding);
       7:     }
       8: }

    实际上,如果采用消息安全模式,SymmetricSecurityBindingElement将会添加进来实现基于消息级别的签名、加密安全措施。这也可以从下面的输出结果看出来:

    1. System.ServiceModel.Channels.TransactionFlowBindingElement
    2. System.ServiceModel.Channels.SymmetricSecurityBindingElement
    3. System.ServiceModel.Channels.BinaryMessageEncodingBindingElement
    4. System.ServiceModel.Channels.TcpTransportBindingElement

    除了单纯的传输安全模式和消息模式之外,NetTcpBinding还支持一种混合的安全模式,该模式的SecurityMode枚举值表示为:SecurityMode.TransportWithMessageCredential。该模式通过传输安全保障数据的一致性和保密性,通过消息安全提供身份验证。关于不同种类的安全模式,将在“安全”一章中进行详细讲解。SslStreamSecurityBindingElement和TransportSecurityBindingElement一起提供该模式的安全,如下面的代码所示:

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         NetTcpBinding binding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential);
       6:         ListAllBindingElements(binding);
       7:     }
       8: }

    输出结果:

    1. System.ServiceModel.Channels.TransactionFlowBindingElement
    2. System.ServiceModel.Channels.TransportSecurityBindingElement
    3. System.ServiceModel.Channels.BinaryMessageEncodingBindingElement
    4. System.ServiceModel.Channels.SslStreamSecurityBindingElement
    5. System.ServiceModel.Channels.TcpTransportBindingElement


    和WsHttpBinding一样,NetTcpBinding也提供对可靠会话的支持,以保障数据包或者消息的可靠、有序传递。不过与WsHttpBinding的实现机制不同的是,基于NetTcpBinding是采用TCP协议固有的可靠传输机制,比如消息确认机制、重发机制等等。下面的代码,通过ReliableSession.Enabled属性让绑定实现对可靠会话的支持:

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         NetTcpBinding binding = new NetTcpBinding();
       6:         binding.ReliableSession.Enabled = true;
       7:         ListAllBindingElements(binding);
       8:     }
       9: }

    和WsHttpBinding一样,通过ReliableSessionBindingElement实现对可靠会话的支持:

    1. System.ServiceModel.Channels.TransactionFlowBindingElement
    2. System.ServiceModel.Channels.ReliableSessionBindingElement
    3. System.ServiceModel.Channels.BinaryMessageEncodingBindingElement
    4. System.ServiceModel.Channels.WindowsStreamSecurityBindingElement
    5. System.ServiceModel.Channels.TcpTransportBindingElement

    由于NetTcpBinding采用TCP作为传输协议,所以它一般只应用于Intranet中;由于采用二进制的消息编码方式,在性能上较之基于文本的编码会有较大的提高;此外,由于和HTTP协议不同,TCP本身就是一个基于双工通信的协议,所以和WsDualBinding一样可以用于基于双工消息交换模式的WCF应用中。

    五、 NetNamedPipeBinding

    NetNamedPipeBinding,顾名思义,就是基于命名管道传输的绑定。命名管道本身可以支持跨机器的通信,而在WCF中对NetNamedPipeBinding作了更加严格的限制,使其只能用于同一台机器的跨进程通信(IPC)。所以在所有的绑定中,NetNamedPipeBinding将是性能最好的绑定类型。

    我们照例通过分析绑定元素的方式来理解绑定本身的特性与能力。先通过下面的代码列出NetNamedPipeBinding默认的绑定元素:

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         NetNamedPipeBinding binding = new NetNamedPipeBinding();
       6:         ListAllBindingElements(binding);
       7:     }
       8: }

    从输出的绑定元素集合,我们可以得出这样的结论:NamedPipeTransportBindingElement实现了基于命名管道的传输;WindowsStreamSecurityBindingElement提供了基于Windows凭证的传输安全保障;BinaryMessageEncodingBindingElement实现了基于二进制的消息编码;而TransactionFlowBindingElement则为事务流转提供支持。

    1. System.ServiceModel.Channels.TransactionFlowBindingElement
    2. System.ServiceModel.Channels.BinaryMessageEncodingBindingElement
    3. System.ServiceModel.Channels.WindowsStreamSecurityBindingElement
    4. System.ServiceModel.Channels.NamedPipeTransportBindingElement

    由于NetNamedPipeBinding的特殊性(提供基于IPC的通信),所以决定了它的一些相关的特性:仅仅支持传输模式的安全(实际上消息安全模式在IPC场景下已经没有意义);客户端凭证之限于Windows。我们可以将安全模式设为None,使其不采用任何安全模式:

       1: class Program
       2: {
       3:     static void Main(string[] args)
       4:     {
       5:         NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
       6:         ListAllBindingElements(binding);
       7:     }
       8: }

    这样,WindowsStreamSecurityBindingElement将从绑定元素集合中剔除:

    1. System.ServiceModel.Channels.TransactionFlowBindingElement
    2. System.ServiceModel.Channels.BinaryMessageEncodingBindingElement
    3. System.ServiceModel.Channels.NamedPipeTransportBindingElement

    除了上述的五种绑定类型,WCF中还定义了其他一些绑定,比如NetMsmqBinding、MsmqIntegrationBinding、WebHttpBinding等等,将会在具体设计到这些特殊的绑定的章节中介绍。

    WCF中的绑定模型:
    [WCF中的Binding模型]之一: Binding模型简介
    [WCF中的Binding模型]之二: 信道与信道栈(Channel and Channel Stack)
    [WCF中的Binding模型]之三:信道监听器(Channel Listener)
    [WCF中的Binding模型]之四:信道工厂(Channel Factory)
    [WCF中的Binding模型]之五:绑定元素(Binding Element)
    [WCF中的Binding模型]之六:从绑定元素认识系统预定义绑定


    作者:Artech
    出处:http://artech.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Centos 7 zabbix 实战应用
    Centos7 Zabbix添加主机、图形、触发器
    Centos7 Zabbix监控部署
    Centos7 Ntp 时间服务器
    Linux 150命令之查看文件及内容处理命令 cat tac less head tail cut
    Kickstart 安装centos7
    Centos7与Centos6的区别
    Linux 150命令之 文件和目录操作命令 chattr lsattr find
    Linux 发展史与vm安装linux centos 6.9
    Linux介绍
  • 原文地址:https://www.cnblogs.com/artech/p/1354691.html
Copyright © 2011-2022 走看看