“學 以致用”,如果僅僅是希望能夠在項目中合理地應用WCF,那麼對於程序員而言,可以有兩種選擇,一種是“知其然而不知其所以然”,只要掌握了WCF的基礎 知識,那麼對於一般的應用就足夠了。要做到這一點就很容易了,微軟秉承了一貫的方式,將WCF這門技術優雅地呈現給開發者,封裝了複雜的實現邏輯,提供了 易於調用的類庫和相關的工具,使得開發者能夠快速地完成WCF程序的開發。另外一種方式自然就是深度挖掘WCF的內部實現了,這是對WCF專家提出的要 求。如果我們要應用WCF實現SOA解決方案,就會遭遇許多WCF的高級應用,如何合理、有效地應用WCF,並根據項目實際情況對WCF進行擴展,就成爲 了WCF專家必須解決的難題。
因此,如果要學習WCF,你必須找準自己學習的動機與目標,然後合理地安排自己的學習進度表,這纔是正確的學習方式。本文試圖對WCF的一些基礎概念作一些試探性的闡述與分析,並以問答的方式組織,希望能夠部分解答一些希望學習WCF,但猶自徘徊在門外的開發者。
1、WCF是什麼?
從 WCF所處的位置來看,它是包含在.NET 3.0(也包括.NET 3.5)之中的。我們注意比較.NET 3.0與.NET 2.0,其實唯一的區別就是.NET 3.0包含了WCF、WPF、WF(或者還有CardSpace)而已。因此,我們認爲WCF是.NET框架的一部分,似乎並不爲過。尤爲關鍵的 是,WCF並不能脫離.NET框架而單獨存在(但非WCF客戶端可以調用WCF服務),因此,雖然WCF是微軟用以應對SOA解決方案的開發需求而專門推 出的,但它並不是例如Spring、Struts那樣的框架,也不是像EJB那樣的容器或者服務器。微軟真正符合SOA企業應用服務器角色的,我想應該是 Biztalk Server。
嚴格的說,WCF就是專門用於服務定製、發佈與運行以及消息傳遞和處理的一組專門類的集合,也就是所謂的 “類庫”。這些類通過一定方式被組織起來,共同協作,併爲開發者提供了一個統一的編程模式。WCF之所以特殊,是在於它所應對的場景與普通的.NET類庫 不同,它主要用於處理進程間乃至於機器之間消息的傳遞與處理,同時它引入了SOA的設計思想,以服務的方式公佈並運行,以方便客戶端跨進程和機器對服務進 行調用。實際上,WCF就是微軟對於分佈式處理的編程技術的集大成者,它將DCOM、Remoting、Web Service、WSE、MSMQ集成在一起,從而降低了分佈式系統開發者的學習曲線,並統一了開發標準。
WCF與其它類庫還有不同的地 方,則在於WCF充分地體現了運行時環境的概念。對於早期使用WCF的開發人員而言,就可能知道如果在.NET 2.0下要開發WCF,還需要專門下載一個Runtime Component 3.0版,其中就包含了WCF、WF等內容。在.NET中一貫存在所謂“宿主”的概念,整個.NET Framework(或者說是CLR)就可以認爲是一個大的宿主,就像Java的虛擬機一樣。由於WCF對服務有着專門的需求,對於服務端,需要發佈和運 行服務;對於客戶端,則需要調用服務;因而對於開發者,就需要編寫定義、發佈、運行、調用服務的相關代碼。而服務就只能運行在特定的宿主上,這些宿主可以 是控制檯應用程序進程、Windows或Web應用程序進程,也可以是Windows服務進程,或者爲最常用的IIS宿主。在宿主內部,則封裝了通道堆 棧,其中又包含了對協議、編碼、消息傳輸、代理的處理。而在通道層的頂部,還提供了一個高級運行時,以針對應用程序的開發人員。
因而,我們可以這樣認爲,WCF是.NET Framework 3.x的一部分,它包含了用於服務定製、發佈與運行以及消息傳遞和處理的運行時環境以及相關類的集合,它提供了在Windows平臺下開發和部署服務的SDK。大致組成如下圖所示:
2、WCF是怎樣運行的?
如 果從宏觀的角度來分析WCF的運行機制,它的實現並不複雜。WCF的體系架構是基於一種攔截機制來實現的,負責傳遞和攔截消息的組件爲通道,在客戶端發出 對服務端服務的調用時,首先會通過一個服務代理對象,將調用方提供的對象序列化到消息中,然後該消息則通過通道進行傳遞。通道不只是包括一個,而是多個通 道對消息進行處理,包括傳輸、消息編碼、管理會話、傳播事務等,但最底層的通道總是傳輸通道。這些通道的構成形成了一個通道堆棧。由於對象已經被序列化, 因而此時通道傳遞的消息可以跨進程或機器進行傳遞,利用傳輸通道傳遞到服務端。服務端的構成與客戶端基本相似,仍然是通過通道棧中最底層的傳輸通道接收消 息,然後解析消息編碼,並一層層地往上傳輸。在服務端的通道棧之上,則是一個分發器(Dispatcher,或者說是調度器),它會首先對消息進行檢查, 然後選擇一個客戶端要調用的操作。在這個過程中,消息會被反序列化。
下圖說明了WCF的整個運行過程:
由 於WCF通過通道的方式傳遞消息,整個通道同時擔當了偵聽器和攔截器的功能,它可以根據服務的定義,在方法執行的前或後執行不同的操作,例如事務、會話管 理、安全等。這些操作在WCF中,大多數都可以以Attribute的方式應用到服務契約上,這樣的實現方式,就類似於採用了AOP(面向服務編程)的方 法爲服務提供了大量的基礎功能,有助於簡化服務開發者的工作。
3、爲什麼我們要選用WCF?
在Windows平臺 下,尤其是在.NET平臺下開發面向服務的應用程序,或者開發分佈式系統,最佳選擇就是WCF。爲什麼呢?原因就在於WCF涵蓋了之前微軟推出的所有用於 分佈式開發的技術,包括Remoting、Web Services、WSE、MSMQ等,並以一種統一的編程模式來實現。
WCF既支持 具有互操作性的Web服務,也能夠實現.NET客戶端與.NET服務端的通信,提供了分佈式事務的支持,同時在安全性上,它完全遵循了WS-*的標準,此 外,它還支持隊列服務,可以非常方便地利用消息隊列完成異步操作與脫機調用。而這些功能,以前的技術都只是部分的實現。如下表所示:
特性 |
Web Service |
.NET Remoting |
Enterprise Services |
WSE |
MSMQ |
WCF |
具有互操作性的Web服務 |
支持 |
|
|
|
|
支持 |
.NET到.NET的通信 |
|
支持 |
|
|
|
支持 |
分佈式事務 |
|
|
支持 |
|
|
支持 |
支持WS標準 |
|
|
|
支持 |
|
支持 |
消息隊列 |
|
|
|
|
支持 |
支持 |
WCF同時也使得面向服務編程更加簡單而統一了。如果採用舊有的技術,由於各種技術的編程模型完全不一致,使得程序的遷移非常的困難。例 如,最初採用.NET Remoting技術開發的分佈式系統,由於業務需求的變化,要求發佈具有互操作性的Web服務,就需要重新定義服務。並且,客戶端的調用方式也發生了變 化,需要添加Web引用,通過UDDI去發現服務。
採用WCF則不然。WCF引入了用通道,它封裝了消息的通信細節,例如編碼、事務處 理、安全等,然後又通過引入綁定的概念,封裝了通道的組成順序與處理細節。最後,引入了獨有的Endpoint元素,集成了地址、綁定和契約之間的“三位 一體”,以最簡單的方式定義和發佈服務。
4、WCF基礎的技術要素有哪些?
WCF的大部分功能都放在一個單獨的程序集System.ServiceModel.dll中。WCF的幾個最重要的技術元素包括:綁定、契約、端點。
如 前所述,綁定封裝了通道的組成順序與處理細節,它直接決定了WCF的通信方式,消息的編碼方式,通道的協議,消息傳遞的可靠性以及安全等內容。通過使用綁 定,我們就無需瞭解消息在WCF通道中的實現細節,從而簡化程序員的開發。正是因爲此,WCF爲開發人員提供了多個內置綁定,基本上涵蓋了WCF應用的大 部分場景。以下是Aaron Skonnard在《WCF深度綁定》一文中列舉的內置綁定:
綁定類名稱 |
傳輸 |
消息編碼 |
消息版本 |
安全模式 |
可靠消息傳送 |
事務流(默認情況下禁用) |
BasicHttpBinding |
HTTP |
文本 |
SOAP 1.1 |
無 |
不支持 |
不支持 |
WSHttpBinding |
HTTP |
文本 |
SOAP 1.2 WS-Addressing 1.0 |
消息 |
禁用 |
WS-AtomicTransactions |
WSDualHttpBinding |
HTTP |
文本 |
SOAP 1.2 WS-Addressing 1.0 |
消息 |
啓用 |
WS-AtomicTransactions |
WSFederationHttpBinding |
HTTP |
文本 |
SOAP 1.2 WS-Addressing 1.0 |
消息 |
禁用 |
WS-AtomicTransactions |
NetTcpBinding |
TCP |
二進制 |
SOAP 1.2 |
傳輸 |
禁用 |
OleTransactions |
NetPeerTcpBinding |
P2P |
二進制 |
SOAP 1.2 |
傳輸 |
不支持 |
不支持 |
NetNamedPipesBinding |
命名管道 |
二進制 |
SOAP 1.2 |
傳輸 |
不支持 |
OleTransactions |
NetMsmqBinding |
MSMQ |
二進制 |
SOAP 1.2 |
消息 |
不支持 |
不支持 |
MsmqIntegrationBinding |
MSMQ |
不支持(使用 WCF 之前的序列化格式) |
不支持 |
傳輸 |
不支持 |
不支持 |
CustomBinding |
您決定 |
您決定 |
您決定 |
您決定 |
您決定 |
您決定 |
每種綁定對應不同的傳輸協議、消息編碼格式和版本以及安全、可靠性和事務模式。WCF也提供了擴展綁定的方式,例如通過CustomBinding或者定義派生與Binding的類。
WCF 的契約包括服務契約、數據契約和消息契約(特別的,還包括了錯誤契約,用於異常的處理)。其中服務契約爲面向服務應用程序的核心,通過它可以定義服務。數 據契約則爲服務所要傳遞的數據。由於服務的調用需要跨進程或機器進行通信,就需要服務數據必須能夠被序列化和反序列化。雖然.NET本身提供了數據的序列 化功能,但WCF的數據契約更加符合服務數據的定義習慣。至於消息契約,則可以將服務數據定義爲消息,包括XML文本格式、MTOM(消息傳輸優化機制) 格式和二進制格式。
綁定(Binding)、契約(Contract)與服務的地址(Address)組合在一起,則形成了終結點(Endpoint),如下圖所示:
Address 是Endpoint的網絡地址,它標記了消息發送的目的地。Binding描述的是如何發送消息,例如消息發送的傳輸協議(如TCP,HTTP),安全 (如SSL,SOAP消息安全)。Contract則描述的是消息所包含的內容,以及消息的組織和操作方式,例如是單向,雙向還是請求/響應方式。
引 入終結點可以說是WCF的一個偉大創舉,通過它使得我們能夠更加容易的發佈和管理服務,尤其是發佈和管理多個服務。每個服務必須至少擁有一個終結點,而客 戶端正是通過終結點知道服務的相關信息,例如地址、消息編碼格式、傳輸協議以及服務的內容,然後在進行正確的調用。最特別的是,同一個服務可以定義多個終 結點,每個終結點可以是不同的地址、不同的綁定方式,以便於滿足多個客戶端的不同需要。而對於服務的發佈者而言,我們只需要管理終結點的配置,就可以完成 對服務的管理,這也爲服務的託管提供了便利。
5、WCF主要包含哪些內容?
Juval的《Programming WCF Services》一書基本已經涵蓋了WCF技術的方方面面。概括來講,主要包括綁定、服務契約、數據契約、消息傳遞、異常處理、實例模式、併發處理、事務處理、安全以及隊列服務等。
綁 定屬於WCF基本的技術要素,是WCF進行通信處理的基礎。瞭解綁定的相關知識,有助於開發WCF應用程序。因爲在不同的業務需求下,可能對通信方式、協 議、消息編碼等多個方面會有不同的要求。在配製、發佈和運行服務時,都需要對綁定進行操作。因而,我們必須掌握WCF內置綁定的相關屬性,熟悉綁定元素的 相關配置。此外,在一些高級應用上,我們還要掌握自定義綁定的方式,瞭解在自定義綁定時,添加綁定元素的方式與順序,瞭解Binding基類的相關屬性和 方法。以及與綁定配置相關的類。
服務契約是WCF的主要處理對象,服務的定義和設置正是通過服務契約實現的。除了瞭解 ServiceContract和OperationContract的基礎應用之外,還需要比較WCF服務編程與普通的.NET編程之間的區別,例如服 務的繼承與多態是怎樣實現的。最重要的是如何根據SOA的思想劃分服務的邊界,確定服務的粒度大小,這需要從系統的易用性、可擴展性、性能等多個方面進行 權衡。
服務契約中關於操作的定義要受到很多約束,其中最重要的就是對數據的處理,這也是WCF引入數據契約的目的。由於WCF的特殊性,因而我們需要了解一些特殊數據類型的序列化方式,例如泛型類型、集合、DataSet等。
約束服務操作定義的還包括對異常的處理,WCF對異常有一套特殊的處理方式,可以根據實際的情況,確定異常消息是否需要進行通信,以及出現異常時,是否要求停止服務實例,或繼續維持會話。
WCF 爲消息傳遞提供了非常大的靈活性。它提供了專門的Message類以及相關的讀寫器,例如XmlDictionaryReader和 XmlDictionaryWriter等對消息進行讀寫,這其中包含了對消息版本、編碼格式、消息標頭和正文等的操作。同時,WCF還提供了消息與方法 之間的映射。在提供系統的互操作性時,瞭解WCF的消息傳遞方式很有必要。
根據不同的需求,WCF將實例模式分爲 PerCall,Single和PerSession三種方式。通過設置服務行爲的InstanceContextMode屬性,來管理服務實例的生存周 期,可以簡化開發人員的工作。我們只需要瞭解這三種實例模式的特性即可。通常情況下,我建議服務採用PerCall模式,如果需要維持服務與客戶端之間的 會話,則可以採用PerSession模式。只有在對性能和可伸縮性沒有太大要求的情況下,纔可以採用Single模式。
關於事務處理、併發處理以及安全,主要都是通過相關的服務行爲進行設置和管理。這些內容都是WCF高級應用所必需掌握的內容,尤其對於開發企業級應用系統而言。至於隊列服務,主要是利用了消息隊列,以實現系統可以脫機訪問服務,並保持服務狀態的同步。
6、WCF主用適用於哪些應用場景?
WCF 本身就是微軟爲了應對SOA戰略所推出的一套基於.NET Framework下的SDK。當我們在Windows平臺下,基於.NET框架開發一套系統,同時要求這套系統需要與其它平臺例如WebLogic、 WebSphere或者JBoss進行交互時,就需要採用WCF技術了。這是因爲WCF的互操作性所決定的。
目前來看,WCF在企業應用 中還沒有得到大量的應用,但隨着開發者對.NET 3.x的深入瞭解,WCF會逐漸深入人心。由於WCF集成了.NET編程開發的習慣,對於.NET開發人員而言,就大大地降低了學習曲線,此外,WCF保 留了對舊有技術包括Web Service、.NET Remoting、MSMQ、WSE的支持,同時對於舊有技術到WCF的遷移也提供了非常好的解決方案。因而,如果.NET人員若要應用SOA的解決方 案,那麼WCF無疑就是最佳選擇。單以開發而論,利用WCF定義服務、公開服務以及運行服務,利用WF實現工作流的設計、運行與管理、利用WPF作爲具有 豐富表現的富客戶端,或者通過AJAX+SilverLight開發調用WCF服務的客戶端,以及通過CardSpace完成對服務安全的設置與管理,就 足以實施一整套的SOA解決方案。同時,WCF還可以結合Biztalk以及Sharepoint,使得SDK能夠搭載於應用服務器之上,更大程度地滿足 企業應用的需要。
除了實施SOA解決方案之外,WCF對於開發分佈式系統而言,也是得天獨厚的。當我們的應用系統需要在多個服務器上運行 不同服務,以支撐大量的訪問負荷、大數據量處理、數據挖掘等工作時,就可以利用WCF開發不同的服務,然後託管在不同的服務器上,此時,整個系統就可以有 效地利用服務器資源,減輕系統負荷。