【WCF】基礎

什麼是WCF

WCF是基於Windows平臺下開關和部署服務的SDK。WCF爲服務提供了運行時環境,使得開發者能夠將CLR類型公開爲服務,又能夠以CLR類型的方式使用服務。WCF是微軟對一系列產品標準定義的實現,包括服務交互、類型轉換、封送以及各種協議的管理。正因如此,WCF才能夠提供服務之間的互操作性。

服務

服務(Service)是公開的一組功能的集合。從軟件設計的角度考慮,軟件設計思想經歷了從函數發展到對象,從對象發展到組件,再從組件發展到服務的幾次變遷。面向服務(ServiceOrientation SO)是一組原則的抽象,是創建面向服務應用程序的最佳實踐。
服務可以是本地的,也可以是遠程的,可以由多個參與方使用任意技術進行開發。服務的客戶端只是使用服務功能的一方。理論上講,客戶端可以是任意的。
客戶端與服務通過消息的發送與接收進行交互。消息可以直接在客戶端與服務之間進行傳遞,也可以通過中間方進行傳遞。WCF中的消息通常是SOAP消息,這些消息與傳輸協議無關。
因爲服務的創建對外界而言是不透明的,所以WCF服務通常通過公開元數據的方式描述可用的功能以及服務可能採用的通信方式。元數據的發佈可以預先定義,它與具體的技術無關。

服務的執行邊界

WCF不允許客戶端直接與服務交互,即使它調用的是本地機器內存中的服務。相反,客戶端總是使用代理(proxy)將調用轉發給服務。代理公開的操作與服務相同,同時還增加了一些管理代理的方法。
WCF允許客戶端跨越執行邊界與服務通信。在同一臺機器中,客戶端可以調用同一個應用程序域中的服務,也可以在同一進程中跨應用程序域調用,甚至跨進程調用。在不同的機器情況下,客戶端可以跨越Internet或者Intrannet的邊界與服務交互。

WCF與位置透明度

WCF要求客戶端保持一致的編程模型,而不用考慮服務的位置。由於所有的交互操作都經由代理完成,要求相同的配置與託管方式,因而對於本地和遠程方式而言,WCF都只需要維持相同的編程模型。

地址

WCF的每一個服務都具有一個唯一的地址(Address)。地址包含兩個重要元素:服務位置傳輸協議,或者是用於服務
通信的傳輸樣式。服務位置包括機器名、站點或網絡、通信端口、管道或隊列,以及一個可選的特定路徑或者URI。
TCP地址
TCP地址採用net.tcp協議進行傳輸。
HTTP地址
HTTP地址使用http協議進行傳輸,也可以利用https進行安全傳輸。HTTP地址通常會被用作對外的基於Internet的服務。
IPC地址
IPC地址使用net.pipe進行傳輸,這意味着它將使用Windows的命名管道機制。在WCF中,使用命名管道的服務只能接收來自同一臺機器的調用。因此,在使用時必須指定明確的本地機器名或者直接命名爲localhost。每臺機器只能打開一個命名管道。
MSMQ地址
MSMQ地址使用net.msmq進行傳輸,即使用了微軟消息隊列機制。使用時必須爲MSMQ地址指定隊列名。如果是處理私有隊列,則必須指定隊列類型,但對於公有隊列而言,隊列類型可以省略。
對等網地址
對等網地址使用net.p2p進行傳輸,它是用了Windows的對等網傳輸機制。

契約

WCF的所有服務都會公開爲契約。契約與平臺無關,是描述服務功能的標準方式。WCF定義了四種類型的契約。
服務契約,服務契約描述了客戶端能夠執行的服務操作。
數據契約,數據契約定義了與服務交互的數據類型。
錯誤契約,錯誤契約定義了服務拋出的錯誤,以及服務處理錯誤和傳遞錯誤到客戶端的方式。
消息契約,消息契約允許服務直接與消息交互。消息契約可以是類型化的,也可以是非類型化的。要求使用消息契約則意味着要自定義應用程序上下文,這樣就可以通過使用自定義消息頭來實現。

服務契約

ServiceContractAttribute定義如下:

[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class, Inherited = false)]
public sealed class ServiceContractAttribute : Attribute
{
    public String Name { get; set; }
    public String Namespace { get; set; }
    //更多成員
}

ServiceContract特性可以將一個CLR接口映射爲與技術無關的服務契約,該特性公開了CLR接口(或者類)作爲WCF契約。WCF契約與類型的訪問限定無關。面向服務的一個原則是服務邊界應該明確
類型的所有成員也不一定就是契約中的一部分。我們必須使用OperationContractAttribute特性顯式地標明那些方法需要暴露爲WCF契約中的一部分。OperationContractAttribute定義如下:

[AttributeUsage(AttributeTargets.Method)]
public sealed class OperationContractAttribute : Attribute
{
    public String Name { get; set; }
    //更多成員
}

服務類還有一些實現上的約束。我們要避免使用帶參構造函數,因爲WCF只能使用默認構造函數。同樣,雖然類可以使用內部的屬性、索引器以及靜態成員,但WCF客戶端卻無法訪問它們。

名稱與命名空間

可以爲契約定義命名空間。契約的命名空間具有與.NET編程相同的目的:確定契約的類型範圍,以降低類型的衝突機率。

託管

WCF服務類不能憑空存在。每個WCF服務都必須託管(host)在Windows進程中,該進程被稱爲宿主進程(Host Process)。單個宿主進程可以託管多個服務,而相同的服務類型也能夠託管在多個宿主進程中。
自託管
需要確定客戶端與服務之間的進程(或機器)邊界時;使用進程內託管,即服務於客戶端處於相同進程中時。
託管應用程序的配置文件通常會列出所有希望託管和公開的服務類型

<system.serviceModel>
    <services>
        <service name = "Namespace.Service">
        ...
        </service>
    </services>
</system.serviceModel>

此外,宿主進程必須在運行時顯式地註冊服務類型,同時爲客戶端的調用打開宿主,因此我們纔要求宿主進程必須在客戶端調用到達之前運行。
創建宿主的方法通常是在Main()方法中調用ServiceHost類。
創建ServiceHost對象時,需要爲ServiceHost的構造函數提供服務類型,至於默認的基地址則是可選的。
每個ServiceHost實例都與特定的服務類型相關,如果宿主進程需要運行多個服務類型,則必須創建與之匹配的多個ServiceHost實例。在宿主程序中,通過調用Open()方法,可以允許調用傳入;通過調用Close()方法終結宿主實例,完成進程中的調用。
ServiceHost實現的ICommunicationObject接口定義了一些高級特性

public interface ICommunicationObject
{
    void Open();
    void Close();
    void Abort();

    event EventHandler Closed;
    event EventHandler Closing;
    event EventHandler Faulted;
    event EventHandler Opened;
    event EventHandler Opening;

    IAsyncResult BeginClose(AsyncCallBack callback, Object state);
    IAsyncResult BeginOpen(AsyncCallBack callback, Object state);
    void EndClose(IAnsycResult result);
    void EndOpen(IAnsycResult result);

    CommunicationState State { get; }
}
public enum CommunicationState
{
    Created,
    Opening,
    Opened,
    Closing,
    Closed,
    Faulted
}

ServiceHost< T >類
ServiceHost< T >類能夠改進WCF提供的ServiceHost類。

public class ServiceHost<T> : ServiceHost
{
    public ServiceHost() : base(typeof(T)) {}
    public ServiceHost(params String[] baseAddresses) : base(typeof(T), baseAddresses)) {}
    public ServiceHost(params Uri[] baseAddresses)) : base(typeof(T), baseAddresses)) {}
    static Uri[] Convert(String[] baseAddresses)
    {
        Converter<String, Uri> convert = (address) => { return new Uri(address); };
        return baseAddresses.ConvertAll(convert);
    }
}

綁定

服務之間的通信方式是多種多樣的,有多種可能的通信模式。
同步的請求/應答消息,或者異步的“即發即棄”消息;
雙向消息;
即時消息或隊列消息;
持久隊列或者可變隊列。
針對消息有許多可能的傳輸協議。同時還包括一些可能的消息編碼格式:純文本編碼格式;二進制編碼格式;MTOM編碼格式。
消息的安全保障多種策略:不實施任何安全策略;只提供傳輸層的安全策略;消息曾的隱私保護與安全策略。WCF還包括多種對客戶端認證與授權的安全策略。
一個綁定封裝了諸如傳輸協議、消息編碼、通信模式、可靠性、安全性、事物傳播以及互操作性等相關選項的集合,使得他們保持一致。理想狀態下,我們希望將所有繁雜的基礎功能模塊從服務代碼中解放出來,允許服務只需要關注業務邏輯的實現。綁定使得開發者能夠基於不同的基礎功能模塊使用相同的服務邏輯。

常用綁定

基本綁定由BasicHttpBinding類提供。基本綁定能夠將WCF服務公開爲傳統的ASMX Web服務,使得舊的客戶端能夠與新的服務協作。基本綁定使得你的服務看起來像是一個傳統的Web服務,能夠基於基本的Web服務信息進行通信。
TCP綁定由NetTcpBinding類提供。TCP綁定使用TCP協議實現在Internet中跨機器的通信。TCP綁定支持多種特性,包括可靠性、事務性、安全性以及WCF之間通信的優化。前提是,它要求客戶端與服務都必須使用WCF。
IPC綁定由NetNamedPipeBinding類提供。它使用命名管道爲同一機器的通信進行傳輸。這種綁定方式最安全,因爲它不能接收來自機器外部的調用。它同時也是性能最佳的綁定,因爲IPC協議比TCP更加輕型。
Web服務(WS)綁定由WSHTTPBinding類提供。WS綁定使用HTTP或者HTTPS進行傳輸,爲基於Internet的通信提供了多種特性(諸如可靠性、事務性與安全性),這些特性均遵循WS-*標準。
WS雙向綁定由WSDualHttpBinding類提供。WS雙向綁定於WS綁定相似,但它還支持從服務到客戶端的雙向通信。對於回調的設置沒有行業標準,因此WSDualHttpBinding並不具有互操作性。
MSMQ綁定由NetMsmqBinding類提供。使用MSMQ進行傳輸,用以提供對斷開的隊列調用的支持。

名字 傳輸協議 編碼格式 互操作性
BasicHttpBinding HTTP/HTTPS Text,MTOM Yes
NetTcpBinding TCP Binary No
NetNamedPipeBinding IPC Binary No
WSHttpBinding HTTP/HTTPS Text,MTOM Yes
WSDualHttpBinding HTTP Text,MTOM No
NetMsmqBinding MSMQ Binary No

終結點

服務與地址、綁定以及契約有關。其中,地址定義了服務的位置,綁定定義了服務通信的方式,契約則定義了服務的內容。終結點就是地址、契約與綁定的混成品。
地址就是類型虛擬表的內存地址,綁定則是CLR,而契約則代表接口本身。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章