概述
每個服務終結點都包含一個地址Address、一個綁定Binding 和一個 契約Contract。契約指定可用的操作,綁定指定如何與服務進行通信,而地址指 定查找服務的位置,在WCF專題系列前5篇中,深入了解了WCF中尋址的細節。本 文為消息如何傳遞之綁定第二部分,將詳細介紹WCF內置的各種綁定元素,綁定 元素之間的順序以及如何創建一個自定義的綁定元素。
在WCF專題系列( 6):消息如何傳遞之綁定Part 1一文中,我提到綁定由綁定元素組成,每個綁 定元素用來描述終結點與客戶端通信方式中的某個方面,在發送或接收消息時, 每個綁定元素都表示一個處理步驟;運行時,綁定元素會創建必要的通道和偵聽 器,用以生成傳出和傳入通道堆棧,其中三種主要的綁定元素是協議綁定元素, 編碼綁定元素以及傳輸綁定元素,下面再對它們重新認識一下。
協議綁 定元素
這些元素表示對消息執行的更高級別的處理步驟,如可靠性、安全性 、事務等處理,由這些綁定元素創建的通道和偵聽器可以添加、移除或修改消息 內容,以符合WS-*系列規范,給定的綁定可以具有0或多個協議綁定元素,WCF中 內置的幾種協議綁定元素,其中包括:
1.ReliableSessionBindingElement:該綁定元素會在堆棧中提供一個可 選層,該可選層可在終結點之間建立可靠會話並配置此會話的行為。所謂的可靠 性,是指SOAP消息可以在不可靠的網絡上(如HTTP)進行可靠的傳遞,保證消息 無重復的、消息次序正確的進行交換,它的原理是:為一組消息設定相同的ID, 根據消息號將消息編組,並根據順序號進行排序,大家可以參考WS-Reliability 和WS-ReliableMessaging協議。它的定義如下所示:
public sealed class ReliableSessionBindingElement
: BindingElement, IPolicyExportExtension
{
public bool Ordered { get; set; }
public ReliableMessagingVersion ReliableMessagingVersion { get; set; }
// 更多成員
}
WCF中內置的幾個綁定已 經包含了ReliableSessionBindingElement,如果要添加該元素到其它綁定上, 可以使用如下配置:
<bindings>
<customBinding>
<binding name="reliabilityhttp">
<reliableSession/>
</binding>
</customBinding>
</bindings>
2.SecurityBindingElement:該綁定元素為WCF 中SOAP消息安全綁定元素的基類,它有三種具體的實現:支持對稱加密通道安全 的SymmetricSecurityBindingElement、支持不對稱加密通道安全的 AsymmetricSecurityBindingElement 和 支持混合模式通道安全的 TransportSecurityBindingElement,如下圖所示:
這些實現為在WS-Security Policy規范中定義的綁定建模,在創建自 定義綁定中,我們需要提供SecurityBindingElement的某一個具體的實現,或者 自定義一個類從SecurityBindingElement繼承。
3. TransactionFlowBindingElement:該綁定元素允許在終結點綁定設置中啟用或 禁用傳入事務流,並允許指定傳入事務所需的協議格式。它的定義如下所示:
public sealed class TransactionFlowBindingElement
: BindingElement, IPolicyExportExtension
{
public TransactionProtocol TransactionProtocol { get; set; }
// 更多 成員
}
在補充的Web服務規范中,有一系列的關於事務處理的規 范,如WS-AtomicTransactions、WS-Coordination等等。
編碼綁定元素
所謂的編碼是將消息轉換為一個字節序列的過程,而解碼是相反的過程。編 碼綁定元素表示消息與准備用於網絡傳輸的編碼之間的轉換,典型的WCF綁定正 好包括一個編碼綁定元素。WCF內置的編碼綁定元素包括 MtomMessageEncodingBindingElement、BinaryMessageEncodingBindingElement 和 TextMessageEncodingBindingElement。 如果未對綁定指定編碼綁定元素, 則使用默認的編碼。當傳輸協議是HTTP時,默認編碼為文本,對於其他傳輸協議 ,默認編碼為二進制。如下圖所示:
1. TextMessageEncodingBindingElement:表示文本方式編碼的XML消 息編碼器,它的優點是互操作性最強,缺點是效率最低。WCF服務或者客戶端通 常可以理解文本XML。但是,將大型二進制數據塊作為文本傳輸不是有效的傳輸 方式,它的定義如下所示:
public sealed class TextMessageEncodingBindingElement
: MessageEncodingBindingElement, IWsdlExportExtension, IPolicyExportExtension
{
public int MaxReadPoolSize { get; set; }
public int MaxWritePoolSize { get; set; }
public override MessageVersion MessageVersion { get; set; }
public Encoding WriteEncoding { get; set; }
public override MessageEncoderFactory CreateMessageEncoderFactory();
// 更多 成員
}
2.BinaryMessageEncodingBindingElement:是指定在編 碼消息時應該使用二進制XML格式的綁定元素,它包含用於指定要使用何種字符 編碼以及SOAP消息與 WS-Addressing版本的選項。二進制編碼的優點是效率最高 ,缺點是互操作性最低,它的定義如下所示:
public sealed class BinaryMessageEncodingBindingElement
: MessageEncodingBindingElement,
IWsdlExportExtension, IPolicyExportExtension
{
public int MaxReadPoolSize { get; set; }
public int MaxSessionSize { get; set; }
public int MaxWritePoolSize { get; set; }
public override MessageVersion MessageVersion { get; set; }
public override MessageEncoderFactory CreateMessageEncoderFactory();
// 更多 成員
}
3.MtomMessageEncodingBindingElement:表示指定使用 消息傳輸優化機制 (MTOM) 編碼的消息所用的字符編碼和消息版本管理以及其他 設置的綁定元素。(MTOM) 是WCF消息中傳輸二進制數據的有效技術。MTOM 編碼 器會嘗試在效率和互操作性之間建立平衡。MTOM 編碼以文本形式傳輸大多數 XML,但通過按原樣傳輸來優化大型二進制數據塊的傳輸,無需將其轉換為 base64編碼格式。它的定義如下所示:
public sealed class MtomMessageEncodingBindingElement
: MessageEncodingBindingElement,
IWsdlExportExtension, IPolicyExportExtension
{
public int MaxBufferSize { get; set; }
public int MaxReadPoolSize { get; set; }
public int MaxWritePoolSize { get; set; }
public override MessageVersion MessageVersion { get; set; }
public Encoding WriteEncoding { get; set; }
public override MessageEncoderFactory CreateMessageEncoderFactory();
// 更多 成員
}
如果以上編碼不能滿足實際的開發需求,我們還可以定 義自己的消息編碼器,在後面的文章中,我將會詳細介紹。
傳輸綁定元 素
這些元素表示傳輸協議上編碼消息的傳輸。典型的WCF綁定正好包括一個從 TransportBindingElement 繼承的傳輸綁定元素。WCF中內置的傳輸綁定元素有 如下幾種:
TcpTransportBindingElement
HttpTransportBindingElement
HttpsTransportBindingElement
NamedPipeTransportBindingElement
PeerTransportBindingElement
MsmqTransportBindingElement
MsmqIntegrationBindingElement
ConnectionOrientedTransportBindingElement
除此之外,還可以 用戶自定義的傳輸綁定元素。
綁定元素順序
在創建綁定時,向綁定中 添加綁定元素的順序非常重要,必須按照如下順序進行:
1.最頂層是一 個允許流事務的TransactionFlowBindingElement元素,可選;
2.接下來 是一個可靠性支持的ReliableSessionBindingElement元素,可選;
3.接 下來是一個安全性支持的SecurityBindingElement元素,可選;
4.在接 下來是消息編碼綁定元素,可以是系統內置的三種消息編碼器之一或者自定義的 消息編碼器,必須具有,但是如果不添加,系統會根據傳輸不同默認添加一個消 息編碼器;
5.最底層是一個傳輸綁定元素,可以是系統內置的幾種傳輸 綁定元素之一或者自定義的傳輸綁定元素。
6.如果是自定義的綁定元素 ,根據綁定元素的功能可以放在以上幾層任意層之間。
如下面的示例代 碼,創建一個自定義的綁定,並向其中添加三個綁定元素:
// 可 靠性支持
ReliableSessionBindingElement reliable =
new ReliableSessionBindingElement();
reliable.Ordered = false;
// 編碼元素
TextMessageEncodingBindingElement text =
new TextMessageEncodingBindingElement();
text.MessageVersion = MessageVersion.Soap11WSAddressingAugust2004;
// 傳輸元素
HttpTransportBindingElement http = new HttpTransportBindingElement ();
http.TransferMode = TransferMode.Streamed;
http.UseDefaultWebProxy = true;
// 自定義綁定
CustomBinding httpBinding = new CustomBinding();
httpBinding.Name = "httpBinding";
httpBinding.Elements.Add(reliable);
httpBinding.Elements.Add (text);
httpBinding.Elements.Add(http);
host.AddServiceEndpoint(typeof(ICalculator), httpBinding,
"http://localhost:8887/Calculator");
自定義綁定元素
當在構造一個新的綁定時,如果系統內置的綁定元素無法滿足需要,可以開發一 個自定義的綁定元素,如自定義的消息綁定元素、自定義的傳輸綁定元素或者任 意一個綁定元素。關於消息綁定元素的自定義,我將在後面消息編碼器一文中進 行介紹,而自定義傳輸綁定元素,也是一個相當負責工作,需要創建相應的自定 義通道組件,所以將會放在介紹完WCF中通道模型之後再詳細講解。總的來說, 實現一個自定義的綁定元素,需要繼承於抽象的基類BindingElement,如下面的 代碼片段:
public class LoggingBindingElement : BindingElement
{
public LoggingBindingElement()
{
}
public LoggingBindingElement (LoggingBindingElement other)
: base(other)
{
}
public override BindingElement Clone()
{
return new LoggingBindingElement(this);
}
public override T GetProperty<T>(BindingContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
return context.GetInnerProperty<T>();
}
}
在後面的文章將會看到一個完整的自定義綁定元素的例子。
總結
本文為消息如何傳遞之綁定第二部分,詳細介紹了WCF內置的各 種綁定元素,綁定元素之間的順序以及如何創建一個自定義的綁定元素。