天天看點

《我的WCF之旅》博文系列彙總

WCF是建構和運作互聯系統的一系列技術的總稱,它是建立在Web

Service架構上的一個全新的通信平台。你可以把它看成是.NET平台上的新一代的Web

Service。WCF為我們提供了安全、可靠的的消息通信,也為我們提供了更好的可互操作性是的我們可以和其他的平台進行“交流”。

微軟斥巨資打造WCF,在我們看來主要出于下面兩個目的:實作其對現有的分布式技術的整合以及順應SOA的浪潮。在WCF之前,微軟已經為了提供了一套完整的基于分布式的技術和産品,這些技術和産品使我們建構一個基于于分布式的互聯系統變得異常簡單。我們熟悉的技術包括Enterprise

Service,.NET Remoting, XML Web Service,

MSMQ等等,這些不同的技術和産品為相同的功能提供了不同的實作。對于技術的發展,我覺得“統一”是一個主線:為了讓基于Web的開發可以采用我們基于Windows

Form的事件驅動、基于控件開發模式,我們有了ASP.NET;為了使具有不同結構的資料(.NET Object, XML,

Relational Data

etc)采用相同的操作方式,我們有了LINQ。同樣,對于一個分布式系統的開發,将不同的分布式技術整合起來,提供一個統一的程式設計模型是絕對有必要的,WCF就是基于這樣的一個目的發展起來的。

但是,如果你認為WCF僅僅是這些不同的分布式技術簡單地組合在一起,那就錯了。WCF在對這些技術進行整合的時候,始終有一個指導方針,那就是SOA。SOA,毫無疑問是今後開發互聯系統的一個趨勢,對于SOA,我想網上充斥着太多的相關的資訊,我在這裡就不做任何介紹了。SOA的發展離不開一個大家能夠一緻尊崇的一個标準,而WS-*

就是這個标準。WCF基本上實作了目前所有的WS-* 标準。

在過去半年之後,我陸陸續續寫了一些關于WCF介紹的一些文章,我把它命名為“我的WCF之旅”,目的在于向大家分享我學習WCF這一段旅程。現在把把這個系列做一個階段性的總結,以飨讀者。

在Microsoft提出.NET戰略以來,先後推出了一系列産品和技術,這些産品和技術為我們在.NET平台下建立企業級的分布式應用提供了很大的

便利。這些技術和産品包括:.NET  Remoting,XML WebSerivce,WSE(2.0,3.0),Enterprise

Service, MSMQ

等等。通過合理利用上面這些分布式的技術完全可以為我們建立的一套适合不同層次需要的分布式構架。但這裡面仍然存在一些問題,那就是上面這些技術和産品隻能解決某一方面的問題;比如.NET

Remoting雖然在.NET平台下是一個很好的依靠,但是考慮到他不能提供不同平台之間的互操作性。另外,這些技術适合用了完全不同的程式設計方式,使得我們很難從容地從其中一種轉移到另一種上來。基于這些原因, 我們需要一套全新的技術整合以上都這些技術,于是我們有了今天的WCF——

Windows Communication

Foundation。WCF建立一套架構,是我們通過一緻的程式設計模式,使用不同的技術建構我們的分布式應用。 

雖然很早開始接觸WCF,但所學的總是零零碎碎。現在開始系統地研究WCF,希望與大家一同分享我的一些所得, 同時希望能通過這樣的一個機會與大家一些探讨WCF,不對的地方希望大家指正。

一開始我們先建立一個簡單程式看WCF如何工作。

WCF實際上是建構了一個架構,這個架構實作了在互聯系統中各個Application之間如何通信。使得Developers和Architect在建構分布式系統中,無需在考慮如何去實作通信相關的問題,更加關注與系統的業務邏輯本身。而在WCF

Infrastructure中,各個Application之間的通信是由Endpoint來實作的。

當我們Host一個WCF

Service的時候,我們必須給他定義一個或多個Endpoint,然後service通過這個定義的Endpoint進行監聽來自Client端的請求。當我們的Application需要調用這個Service的時候,因為Client

和Service是通過Endpoint的進行通信的,是以我們必須為我們的Application定義Client端的Endpoint。隻有當

Client的Endpoint和Service端某個

Endpoint互相比對(Service端可以為一個Service定義多個Endpoint),Client端的請求才能被Service端監聽到。也就是說,我們隻有在Client具有一個與Service端完全比對的Endpoint,我們才能調用這個Service。而這種比對是比較嚴格的,比如從比對Address方面,Client端和Service端的Endpoint

Address不僅僅在URI上要完全比對Service,他們的Headers也需要互相比對。對于Binding,

一般地,Client需要有一個與Service端完全一樣的Binding,他們之間才能通信。

作為Remoting中實作雙向通信對比,來讨論一下WCF的雙向通信。為了使我們能夠更好地對比雙向通信在

Remoting中和WCF中的實作,我們的Sample采用一樣的業務邏輯——調用一個數學計算的遠端調用,除了傳遞相應的操作數之外,我們還傳遞一個對象,這個對象可以在Server端中回調

(Callback) 把運算結果在Client端顯示出來。

在分布式系統中,一個Application與另一個Application之間進行互動,必然需要攜帶資料。系統互動完全是應

Message的方式進行的,Message是XML,當然置于Message中的資料也應該是XML(XML

Infoset)。如何處理這些互動的資料,我們可能首先想到的就是直接處理XML,我們可以在XML級别通過相關的XML技術——XSD,XPath,

XSLT來操作資料。但是要使我們處理後的XML需要和要求的完全一緻,這樣的工作無疑是非常枯燥乏味而且費時費力的。而我們最擅長的就是使用.NET對象來封裝我們的資料。如何使我們創造的對象能夠有效地轉化成結構化的XML

Infoset,就是今天我們要講的内容——Serialization。

給予XML的WCF,并不具有對Overloading的原生支援,但是Overloading是.NET

Framework原生支援的。通過Overloading,我們可以使用同名的方法來定義不同的操作,進而使我們的Code顯得更加優雅(Elegant)。要是Overloading在WCF中可以使用,WCF必須提供這樣的一個Mapping——是被重載的具有相同方法的的方法

Mapping到不同的Operation上。而提供着一個功能的就是ServiceContract。下面我們來結合一個Sample來看如何在WCF

中使用Overloading。

針對一個讀者将我的demo從Console Application移植到Windows Form而出現TimeoutException,進一步了解WCF的Messaging。

而在程式設計模型層面,OO仍然是不可替代的程式設計模式。是以OO應用于Programming,而SO則更多地運用在Architecture。既然是這樣,我們必須有一種調和劑來調和這兩個運用不同原理的兩個層面的差異,實作他們之間的無縫的結合。比如如何來對繼承,多态,重載等基于OO行為的支援。在這方面,WCF為我們提供了很好的解決方案。是以我說WCF不但是為基于SOA的應用架構提供了技術支援,還通過相關的機制完成我們提出的這個“調和劑”的使命。

在這裡我們通過一個Sample來讨論WCF對繼承的支援。這個Sample中,我們通過一個WCF Service實作了提供天氣資訊的功能,或者說,我們實作了一個用作天氣預報的WCF Service。

在一個C/S(Client/Service)場景中,Context無關性展現在Client對Service的每次調用都是完全不相關的。但是在有些情況下,我們卻希望系統為我們建立一個Session來保留某個Client和Service的進行互動的狀态。是以,像Web

Service一樣,WCF也提供了對Session的支援。對于WCF來說,Client和Service之間的互動都通過Soap

Message來實作的,每次互動的過程就是一次簡單的Message

Exchange。是以從Messaging的角度來講,WCF的Session就是把某個把相關的Message

Exchange納入同一個Conversation。每個Session用一個Session ID來唯一辨別。

真正的邏輯實作是通過調用真正的Service

instance中。在一個分布式環境中,我們把通過Client的調用來建立最終的Service

Instance的過程叫做Activation。在Remoting中我們有兩種Activation方式:Server

Activation(Singleton和SingleCall),Client

Activation。實際上對WCF也具有相似的Activation。不過WCF不僅僅建立對應的Service

Instance,而且還建構相關的Context, 我們把這些統稱為Instance

Context。不同的Activation方式在WCF中展現為的Instance context model。不同的Instance

Context Mode展現為Proxy、Service 調用和Service Instance之間的對應關系。可以這麼說,Instance

Context Mode決定着不同的Session表現。

無論對于Web

Service還是WCF,Client和Service之間互動的唯一形式是通過發送和接收Soap Message。在我們對Web

Service和WCF進行深入學習的時候,借助一些Soap Trace 工具對Soap

Message進行深入剖析是非常有必要的。在這些工具之中,我覺得最好用的就是Microsoft Soap Toolkit中的Soap Trace

Utility和tcpTrace。我們今天就來講講如何在WCF中使用tcpTrace這個工具。

在任何Application的開發中,對不可預知的異常進行troubleshooting時,異常處理顯得尤為重要。對于一般的.NET系統來說,我們簡單地借助try/catch可以很容易地實作這一功能。但是對于一個分布式的環境來說,異常處理就沒有那麼簡單了。按照面向服務的原則,我們把一些可複用的業務邏輯以Service的形式實作,各個Service處于一個自治的環境中,一個Service需要和另一個Service進行互動,隻需要獲得該Service的描述(Description)就可以了(比如

WSDL,Schema和Strategy)。借助标準的、平台無關的通信構架,各個Service之間通過标準的Soap

Message進行互動。Service Description、Standard Communication

Infrastructure、Soap Message based

Communication促使各Service以松耦合的方式結合在一起。但是由于各個Service是自治的,如果一個Service調用另一個

Service,在服務提供方抛出的Exception必須被封裝在Soap

Message中,方能被處于另一方的服務的使用者獲得、進而進行合理的處理。下面我們結合一個簡單的Sample來簡單地介紹我們可以通過哪些方式在

WCF中進行Exception Handling。

在一個基于面向服務的分布式環境中,借助一個标準的、平台無關的Communication

Infrastructure,各個Service通過SOAP Message實作互相之間的互動。這個互動的過程實際上就是Message

Exchange的過程。WCF支援不同形式的Message Exchange,我們把這稱之為Message Exchange

Pattern(MEP), 常見的MEP包括:

Request/Reply,Request/Forget(One-way)和Duplex。通過采用Duplex

MEP,我們可以實作在Service端Callback

Client的操作。雖然WCF為我們實作底層的通信細節,使得我們把精力轉移到業務邏輯的實作,進行Transport無關的程式設計,但是對底層

Transport的了解有利于我們根據所處的具體環境選擇一個合适的Transport。說到Transport, WCF

經常使用的是以下4個:Http,TCP,Named

Pipe,MSMQ。由于不同協定自身的差異,他們對具體MEP的支援方式也會不同,我們今天就來談談Http和TCP對Duplex的支援。

在一個分布式的環境中,我們往往需要根據具體的情況采用不同的方式進行資料的傳輸。比如在一個Intranet内,我們一般通過TCP進行高效的資料通信;而在一個Internet的環境中,我們則通常使用Http進行跨平台的資料交換。而這些通信方式具有一個顯著的特點,那就是他們是基于

Connection的,也就是說,互動雙方在進行通信的時候必須保證有一個可用的Connection存在于他們之間。而在某些時候,比如那些使用撥接上網的使用者、以及使用便攜式計算機的使用者,我們不能保證在他們和需要通路的Server之間有一個的可靠的連接配接,在這種情況下,基于Messaging

Queue的連接配接就顯得尤為重要了。我們今天就來談談在WCF中如何使用MSMQ。

我們知道MSMQ天生就具有異步的特性,它隻能以One-way的MEP(Message

Exchange Pattern)進行通信。Client和Service之間采用One-way

MEP的話就意味着Client調用Service之後立即傳回,它無法獲得Service的執行結果,也無法捕捉Service運作的

Exception。

但是在有些場景 中,這是無法容忍的。再拿我在上一篇文章的Order

Delivery的例子來說。Client向Service送出了Order,卻無法确認該Order是否被Service正确處理,這顯然是不能接受的。我們今天就來讨論一下,如何建立一個Responsive

Service來解決這個問題:Client不再是對Service的執行情況一無所知,它可以獲知Order是否被Service正确處理了。

作者:蔣金楠

微信公衆賬号:大内老A

如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識别二維碼)關注個人公衆号(原來公衆帳号蔣金楠的自媒體将會停用)。

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

<a href="http://www.cnblogs.com/artech/archive/2007/09/15/893838.html" target="_blank">原文連結</a>