`
varsoft
  • 浏览: 2422543 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

[WCF中的Binding模型]之六(完结篇):从绑定元素认识系统预定义绑定

阅读更多

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

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

一、BasicHttpBinding

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

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

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

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

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

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

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

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

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

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

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

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

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

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

那么我们我们最终输出的绑定元素列表中,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
<!--CRLF-->
   2: {
<!--CRLF-->
   3:     static void Main(string[] args)
<!--CRLF-->
   4:     {
<!--CRLF-->
   5:         WsHttpBinding binding = new WsHttpBinding();
<!--CRLF-->
   6:         ListAllBindingElements(binding);
<!--CRLF-->
   7:     }
<!--CRLF-->
   8: }
<!--CRLF-->

从下面的输出来看,从上到下一共包含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-T(Transactions)为事务定义了规范,而在WCF中,则通过TransactionFlowBindingElement实现了WS-Transactions规范。

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

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

那么基于消息模式的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
<!--CRLF-->
   2: {
<!--CRLF-->
   3:     static void Main(string[] args)
<!--CRLF-->
   4:     {
<!--CRLF-->
   5:         WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message, true);
<!--CRLF-->
   6:         ListAllBindingElements(binding);
<!--CRLF-->
   7:     }
<!--CRLF-->
   8: }
<!--CRLF-->

最终的输出将包含五个绑定元素,第二个就是实现了可靠会话的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
<!--CRLF-->
   2: {
<!--CRLF-->
   3:     static void Main(string[] args)
<!--CRLF-->
   4:     {
<!--CRLF-->
   5:         WSDualHttpBinding binding = new WSDualHttpBinding();
<!--CRLF-->
   6:         ListAllBindingElements(binding);
<!--CRLF-->
   7:     }
<!--CRLF-->
   8: }
<!--CRLF-->

下面列出了输出的所有绑定元素,从中可以看出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
<!--CRLF-->
   2: {
<!--CRLF-->
   3:     static void Main(string[] args)
<!--CRLF-->
   4:     {
<!--CRLF-->
   5:         NetTcpBinding binding = new NetTcpBinding();
<!--CRLF-->
   6:         ListAllBindingElements(binding);
<!--CRLF-->
   7:     }
<!--CRLF-->
   8: }
<!--CRLF-->

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

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

上面涉及的四个绑定元素,除了WindowsStreamSecurityBindingElement,相信有了前面的介绍,读者不会感到陌生。在这里我们来简单讨论一下WindowsStreamSecurityBindingElement。WindowsStreamSecurityBindingElement继承自System.ServiceModel.Channels.StreamUpgradeBindingElement,StreamUpgradeBindingElement是一种特殊的绑定元素。前面我们讲了,绑定元素的使命在于对相应信道的创建,而StreamUpgradeBindingElement的特别之处在于它并会参与信道的创建。StreamUpgradeBindingElement一般应用于基于流的传输(Stream O

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics