引言
從本質上說,WCF是一個通信服務框架,它允許我們使用不同的傳輸 協議,使用不同的消息編碼形式,跟不同的WS-*系列規范交互,而所有這些細節 都是由通道堆棧來處理的。為了簡化這些處理,在WCF中提供了兩種模型,一是 針對開發者的應用程序編程模型;二是用來通信的通道模型,這樣對於開發者來 說,只要了解應用程序編程模型就足夠了,而不會涉及到通道模型,然而,對於 通道模型進行必要的學習,可以讓我們真正理解WCF中“通信”概念 ,了解WCF的 整個架構體系,從而構建出更加健壯的WCF服務或者對WCF框架進行 擴展。在本文中,我們將進行深度了解WCF中的通道模型是如何設計的。
通道模型概述
在WCF中,提供了一系列的接口和其它類型模型,它們為消息的 發送和接收提供了一個底層的編程模型,該模型稱之為WCF通道模型。在通道模 型中,一個很重要的概念是通道堆棧,它是具有一個或多個消息處理通道的分層 的通信堆棧,堆棧中放置了各種類型的通道,用來對象進行處理,如在通道堆棧 的最底層放置了傳輸通道,它負責使通道堆棧適應基礎傳輸,如圖1所示:
圖1
在通道堆棧中,不僅僅提供消息的傳輸方式,還提供了其 它諸如對消息的內容或者消息頭進行處理的功能,這些功能同樣是以通道的方式 放置在通道堆棧中,甚至於我們可以編寫自己的通道,加入到通道堆棧中。
消息在通道堆棧中傳輸時,將作為Message對象流過通信堆棧,如傳輸通 道負責在發送方和接收方之間轉換消息,之後消息將通過傳輸通道繼續往上流, 依次經過通道堆棧中的各個通道,這些通道各自負責提供一種通信功能,如在消 息頭中添加信息,對消息的正文進行加密等等。
通道對象模型
通道對 象模型是實現通道、通道偵聽器和通道工廠所必需的一組核心接口。還提供一些 基類以輔助自定義實現。可以看到通道模型中最重要的有三組接口:通道、通道 偵聽器和通道工廠。每個通道均實現一個或多個接口,稱為通道形狀接口或通道 形狀;通道偵聽器負責偵聽傳入消息,即在消息的接收端,然後通過由通道偵聽 器創建的通道將這些消息傳送到上面的層;通道工廠負責創建通道用於發送消息 ,即在消息的發送方,並在通道工廠關閉時,關閉通道工廠創建的所有通道。
在通道模型中,最重要的一個接口是ICommunicationObject,它定義了 所有通信對象實現的基本狀態機的核心接口,自定義通道通信對象可以直接實現 ICommunicationObject,如圖2所示:
圖2
只有圖2中的這些接口,才屬於WCF的通道模型,在WCF中同 樣提供了一些基類如CommunicationObject、ChannelFactoryBase等,在實現自 定義的通道通信對象時,也可以直接繼承於這些基類,但要注意,這些基類僅僅 是為實現自定義通道通信對象提供了方便,它們本身並不屬於通道模型的一部分 。
ICommunicationObject接口為WCF中所有面向通信的對象提供了契約, 除了通道、通道偵聽器、通道工廠外,還有調度程序和服務主機,定義了基本狀 態的協定。它包括一組用於啟動狀態轉換的打開、關閉和中止方法,打開和關閉 方法的異步版本,一組提供狀態轉換通知的事件和一個個用於檢查對象狀態的公 開State屬性,它的定義如下所示:
public interface ICommunicationObject
{
// 狀態屬性
CommunicationState State { get; }
// 事件
event EventHandler Closed;
event EventHandler Closing;
event EventHandler Faulted;
event EventHandler Opened;
event EventHandler Opening;
// 方法
void Abort ();
void Close();
void Close(TimeSpan timeout);
void Open();
void Open(TimeSpan timeout);
// 異步方法
IAsyncResult BeginClose(AsyncCallback callback, object state);
IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state);
IAsyncResult BeginOpen(AsyncCallback callback, object state);
IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state);
void EndClose(IAsyncResult result);
void EndOpen (IAsyncResult result);
}
ICommunicationObject 的初始狀態 是“已創建”,此時可以配置它的各種屬性。 一旦處於“已打 開”狀態,對象就可用於發送和接收消息,但它的屬性將視為不可變。 一 旦處在“正在關閉”狀態,對象就不能再處理新的發送或接收請求, 但在到達“關閉”超時前有可能完成現有的請求。 如果發生不可恢 復的錯誤,則對象將轉換到“出錯”狀態,此時可以檢查該對象以獲 取有關錯誤的信息,該對象最終將關閉。 處於“已關閉”狀態時, 該對象實質上已到達狀態機的終點。 對象一旦從一個狀態轉換到下一個狀態, 它將不會返回至前一狀態,整個過程圖3所示:
圖 3
通道形狀
每個通道均實現一個或多個接口,稱為通道 形狀接口或通道形狀。通道形狀的最底層是 IChannel 接口,該接口提供一個 GetProperty<T> 方法,用作訪問由通道堆棧中的通道公開的任意功能的 分層機制。擴展 IChannel 的五種通道形狀為:
1.IInputChannel:用於 接收消息
2.IOutputChannel:用於發送消息
3.IRequestChannel :用於發送請求
4.IReplyChannel:用於發送回復
5.IDuplexChannel:用於雙向消息傳遞
它們之間的關系如圖4所 示:
圖 4
其實可以看出,IDuplexChannel接口是IInputChannel和 IOutputChannel接口的聯合,所有的通道形狀都同時擴展了 ICommunicationObject和IChannel。這5種通道模型分別對應於不同的消息交換 模式,在使用數據報模式時,消息發送方通道實現了IOutputChannel接口,而消 息接收方通道實現了IInputChannel接口;在請求響應模式中,客戶端通道實現 IRequestChannel接口,而服務通道實現IReplyChannel接口;在雙工通信模式中 ,由於雙方都能發送和接收消息,客戶端和服務通道實現了IDuplexChannel接口 ,如圖5所示:
圖 5
服務端通道
在通道對象模型中,除了IChannel接口, 另外一個接口IChannelListener用於消息的接收端,通過綁定來生成通道偵聽器 (在綁定中有關於協議、編碼和傳輸的信息,關於綁定可以參考WCF專題系列(6 ):消息如何傳遞之綁定Part 1),用於偵聽傳入的消息。通道偵聽器負責創建 通道並從下面的層或者從網絡接收消息,收到的消息將借助於通道偵聽器所創建 的通道傳送到上面的層中。整個過程如圖6所示:
圖 6
在WCF的內部,對於消息的每一個處理(即通道堆棧中的 通道),都會對應一個內部的通道偵聽器,如針對事務處理的 TransactionChannelListener和使用TCP傳輸的TcpChannelListener,分別用於 創建各自對應的通道。
客戶端通道
在WCF的客戶端,通道的創建使用 通道工廠,創建的這些通道負責獲取來自上一層的消息,對消息進行必要的處理 ,然後將消息發送到下一層,如圖7所示:
圖 7
在WCF內部,同樣對於消息的每一個處理,都會有相應的 通道工廠,如使用TCP傳輸的TcpChannelFactory,用於創建對應的通道。
總結
本文詳細介紹了WCF中的通道編程模型以及關於通道、通道監聽 器和通道工廠等,大多數都是純理論的知識,在下一篇文章中,將會通過一個示 例來加深對於本文所講知識的認識。