官术网_书友最值得收藏!

3.6.1 系統綁定

由于綁定對象由一系列有序的綁定元素組成,綁定元素最終決定著信道棧中信道的組成,而信道的組成最終又決定了信道棧對消息進行處理的方式和能力,所以要確定綁定的特性和能力,我們可以通過查看其綁定元素的構成來一窺究竟。為此我寫了一個簡單的方法,以列出一個具體綁定對象的所有綁定元素,在介紹一個個具體的系統綁定時,我會使用該方法。

        static void ListAllBindingElements(Binding binding)
        {
            BindingElementCollection elements = binding.CreateBindingElements();
            for (int i = 0; i < elements.Count; i++)
            {
                Console.WriteLine("{0}. {1}", i+1, elements[i].GetType().FullName);
            }
        }

BasicHttpBinding

我們通過調用默認的構造函數創建一個綁定對象,并借助上面的ListAllBindingElements方法列出該綁定對象所有的綁定元素。

        class Program
        {
            static void Main(string[] args)
            {
                BasicHttpBinding binding = new BasicHttpBinding();
                ListAllBindingElements(binding);
            }
        }

將會得到如下的輸出,從中可以看出在默認的情況下,一個BasicHttpBinding包含兩個最基本的綁定元素:作為傳輸元素的HttpTransportBindingElement和作為消息編碼元素的

TextMessageEncodingBindingElement。所以BasicHttpBinding在默認的情況下采用HTTP和基于文本的消息編碼方式。

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

除了提供最基本的傳輸和編碼功能外,BasicHttpBinding還提供了對安全的支持,無論是基于傳輸的安全還是基于消息的安全,都可以通過對綁定進行相應的設置實現。在下面的代碼中,在創建BasicHttpBinding對象的時候,指定一個BasicHttpSecurityMode.Transport參數將安全模式設為傳輸安全模式。

        class Program
        {
            static void Main(string[] args)
            {
                BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.
                  Transport);
                ListAllBindingElements(binding);
            }
        }

在最終的輸出中可以看到,傳輸綁定元素由HttpTransportBindingElement變成了

HttpsTransportBindingElement,由此可以看出BasicHttpBinding通過HTTPS實現傳輸安全。

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

如果我們將其設置成基于消息的安全模式,并將客戶端的憑證類型(Client Credential Type)設為證書(Certificate,這對于基于消息安全模式的BasicHttpBinding是必須的)。

        class Program
        {
            static void Main(string[] args)
            {
              BasicHttpBinding binding = new BasicHttpBinding
                  (BasicHttpSecurityMode.Message);
              binding.Security.Message.ClientCredentialType =
                  BasicHttpMessageCredentialType.Certificate;
              ListAllBindingElements(binding);
            }
        }

那么通過輸出,我們可以看到在原有綁定元素之上,又多出了一個新的綁定元素:AsymmetricSecurityBindingElement,該元素通過非對稱加密(也就是基于X509證書的加密)的方式實現了基于消息的安全。

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

對于BasicHttpBinding來說,默認采用基于文本的消息編碼方式(TextMessageEncodingBindingElement),實際上BasicHttpBinding還提供基于MTOM編碼方式的支持。我們可以通過編程或配置的方式對消息編碼方式進行顯式指定。在下面的代碼中,通過MessageEncoding屬性將編碼方式指定為:WSMessageEncoding.Mtom。

        class Program
        {
            static void Main(string[] args)
            {
                BasicHttpBinding binding = new BasicHttpBinding();
                binding.MessageEncoding = WSMessageEncoding.Mtom;
                ListAllBindingElements(binding);
            }
        }

那么在最終輸出的綁定元素列表中,TextMessageEncodingBindingElement將會被實現MTOM消息編碼的MtomMessageEncodingBindingElement代替。

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

BasicHttpBinding是WS-BP 1.1 Spec標準的,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

我們先通過下面的方式列出在默認條件下(通過默認的構造函數創建WsHttpBinding對象)該綁定對象具有的所有綁定元素。

        class Program
        {
            static void Main(string[] args)
            {
                WsHttpBinding binding = new WsHttpBinding();
                ListAllBindingElements(binding);
            }
        }

從下面的輸出來看,從上到下一共包含4個綁定元素:TransactionFlowBindingElement、SymmetricSecurityBindingElement、TextMessageEncodingBindingElement和HttpTransport-BindingElement。TransactionFlowBindingElement實現了對事務流轉;SymmetricSecurity-BindingElement通過對稱加密的方式實現基于消息的安全;TextMessageEncodingBinding-Element和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設置為基于傳輸的安全模式。

        class Program
        {
            static void Main(string[] args)
            {
                WsHttpBinding binding = new WsHttpBinding(SecurityMode.Transport);
                ListAllBindingElements(binding);
            }
        }

那么基于消息模式的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對可靠會話的支持(第二個參數代表是否支持可靠會話)。

        class Program
        {
            static void Main(string[] args)
            {
                WSHttpBinding binding=new WSHttpBinding(SecurityMode.Message,true);
                ListAllBindingElements(binding);
            }
        }

最終的輸出將包含5個綁定元素,第2個就是實現了可靠會話的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

在前面對消息交換模式的介紹中,我們談到3種典型的消息交換模式:單向的數據報模式、請求/回復模式和雙工模式。WsDualHttpBinding就是專門為HTTP傳輸下雙工消息交換模式設計的。

除了基于傳輸的安全之外,WsHttpBinding的所有特性都被WsDualHttpBinding繼承下來,這包括:基于HTTP的傳輸、基于文本和MTOM的消息編碼、WS-Security、WS-Transactions、WS-Reliable Messaging(Reliable Session)等。我們仍然通過輸出綁定元素的方式證明這一點。

        class Program
        {
            static void Main(string[] args)
            {
                WSDualHttpBinding binding = new WSDualHttpBinding();
                ListAllBindingElements(binding);
            }
        }

下面列出了輸出的所有綁定元素,從中可以看出TransactionFlowBindingElement對WS-Transactions的支持;ReliableSessionBindingElement對WS-RM的支持;SymmetricSecurityBindingElement對WS-Security的支持;這些綁定元素和TextMessageEncodingBindingElement、HttpTransportBindingElement都是與WsHttpBinding共有的,而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

對于WsHttpBinding和WsDualHttpBinding的比較,還有一點值得注意的是在默認情況下,WsHttpBinding并沒有ReliableSessionBindingElement,也就是說在默認的情況下,WsHttpBinding并不支持可靠會話,而對于基于雙工通信的WsDualHttpBinding,可靠會話則是必須的。至于WsDualHttpBinding為何不支持基于傳輸的安全,原因也很簡單,因為HTTP協議下的傳輸安全通過HTTPS(SSL)實現,HTTPS依賴于一個真正意義上的Web站點,也就是只有訪問一個真正意義上Web站點資源的前提下,HTTPS才會有有意義。而對于雙工通信來說,由于客戶端滿足這樣要求,所以從服務端回調客戶端的傳輸安全是無法確保的。

雙工通信需要一個雙工的通信通道,但是屬性為TCP/IP的讀者應該很清楚,HTTP協議僅僅是一個單純的請求/回復通信協議,也就是說基于HTTP的通信通道不支持雙工通信,那么WsDualHttpBinding又是如何在HTTP傳輸協議上實現雙工通信的呢?答案很簡單,WsDualHttpBinding采用了兩個HTTP通道。

NetTcpBinding

到此為止,我們一共介紹了3種類型的綁定。從對于傳輸協議的支持來看,它們都是基于HTTP或HTTPS的綁定;從對標準的支持看來,BasicHttpBinding提供對WS-BP 1.1的支持,WsHttpBinding和WsDualHttpBinding則對WS-*新協議提供很好的支持,比如WS-Transactions、WS-Reliable Messaging、WS-Security等;從消息編碼的角度來看,它們均支持基于純文本的消息編碼和MTOM編碼。除了WsDualHttpBinding(受到雙向通信的制約),這些屬性都決定了這兩種綁定具有較好的互操作性,也就是說,對于此兩種綁定的應用并不限于基于.NET平臺應用的交互,如果通過這些綁定寄宿服務,其他平臺的客戶端可以調用服務,同理我們也可以利用基于這些綁定的客戶端訪問其他非.NET平臺的Web服務,只要對方支持相應的標準。

接下來要介紹的另外3種綁定,相比之下它們就不具有如此好的互操作性了,它們只能應用于單純的WCF客戶端和服務之間的交互。它們基于不同的傳輸協議,先來介紹基于TCP的NetTcpBinding。

照例采用列出綁定元素列表的方式分析綁定的特性,我們先通過下面的代碼看看一個采用默認構造函數創建的NetTcpBinding對象會包含哪些綁定元素。

        class Program
        {
            static void Main(string[] args)
            {
                NetTcpBinding binding = new NetTcpBinding();
                ListAllBindingElements(binding);
            }
        }

程序運行后,下面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

上面涉及的4個綁定元素,除了WindowsStreamSecurityBindingElement外,相信有了前面的介紹,讀者對其他3個都不會感到陌生。在這里我們來簡單討論一下WindowsStreamSecurityBindingElement。WindowsStreamSecurityBindingElement繼承自System.ServiceModel.Channels.StreamUpgradeBindingElement,StreamUpgradeBindingElement是一種特殊的綁定元素。前面講了,綁定元素的使命在于對相應信道的創建,而StreamUpgradeBindingElement的特別之處在于它并不參與信道的創建。StreamUpgradeBindingElement一般應用于基于流的傳輸,比如TCP、命名管道等。它一般位于TransportBindingElement之上,在傳輸層基礎上提供進一步的升級處理(Transport Upgrade),比如安全加密、壓縮等。WindowsStreamSecurityBindingElement在這里的提供基于Windows客戶端憑證的傳輸安全,與之相對的,還有一個System.ServiceModel. Channels.SslStreamSecurityBindingElement,它提供基于SSL的傳輸安全。如果將綁定的客戶端憑證的類型改成Certificate或None,SslStreamSecurityBindingElement將會被采用。

        class Program
        {
            static void Main(string[] args)
            {
                NetTcpBinding binding = new NetTcpBinding();
            binding.Security.Transport.ClientCredentialType =
              TcpClientCredentialType.Certificate;
                ListAllBindingElements(binding);
            }
        }

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。

        class Program
        {
            static void Main(string[] args)
            {
                NetTcpBinding binding = new NetTcpBinding(SecurityMode.Message);
                ListAllBindingElements(binding);
            }
        }

實際上,如果采用消息安全模式,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一起提供該模式的安全。

        class Program
        {
            static void Main(string[] args)
            {
                NetTcpBinding binding = new NetTcpBinding(SecurityMode.
                  TransportWithMessageCredential);
                ListAllBindingElements(binding);
            }
        }

輸出結果:

        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屬性讓綁定實現對可靠會話的支持。

        class Program
        {
            static void Main(string[] args)
            {
                NetTcpBinding binding = new NetTcpBinding();
                binding.ReliableSession.Enabled = true;
                ListAllBindingElements(binding);
            }
        }

輸出結果:

        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默認的綁定元素。

        class Program
        {
            static void Main(string[] args)
            {
                NetNamedPipeBinding binding = new NetNamedPipeBinding();
                ListAllBindingElements(binding);
            }
        }

從輸出的綁定元素集合,我們可以得出這樣的結論: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,使其不采用任何安全模式。

        class Program
        {
            static void Main(string[] args)
            {
                NetNamedPipeBinding binding = new NetNamedPipeBinding
                  (NetNamedPipeSecurityMode.None);
                ListAllBindingElements(binding);
            }
        }

這樣,WindowsStreamSecurityBindingElement將從綁定元素集合中剔除。

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

除了上述的5種綁定類型,WCF中還定義了其他一些綁定,比如NetMsmqBinding、MsmqIntegrationBinding、WebHttpBinding等,將會在具體設計到這些特殊的綁定章節中介紹。

主站蜘蛛池模板: 延津县| 赣州市| 姜堰市| 高要市| 万州区| 麦盖提县| 铁力市| 昌图县| 辽阳市| 拜泉县| 铁岭县| 乌什县| 娱乐| 察哈| 陆良县| 南开区| 屏山县| 定远县| 宽城| 连山| 丰城市| 平陆县| 左贡县| 文登市| 博湖县| 凤阳县| 光山县| 札达县| 开原市| 大田县| 沙坪坝区| 永登县| 五原县| 潜山县| 瓦房店市| 睢宁县| 毕节市| 房产| 格尔木市| 顺义区| 滦平县|