概述
眾所周知,WCF服務的所有通信都是通過服務的終結點發生的,每個 服務終結點都包含一個地址Address、一個綁定Binding 和一個契約Contract。 契約指定可用的操作,綁定指定如何與服務進行通信,而地址指定查找服務的位 置,即非常經典的“ABC”。WCF用多種不同的通信協議為公開服務終 結點和與其通信提供了靈活的模式,在WCF專題系列的第一部分,我將圍繞終結 點的尋址細節展開討論,再此之前,我們先看一下WCF的編程模型,如圖1所示:
圖1
Web服務尋址規范
在 WCF 中,終結點地址是按照Web服 務尋址 WS-Addressing 規范中的定義建立終結點引用(Endpoint Reference, EPR)的模型,我們有必要對Web服務尋址規范來做一個認識,這裡先提出一個問 題,為什麼需要Web服務尋址?一方面SOAP如果要做到真正的與傳輸協議無關, 就要以一種與傳輸協議無關的方式來定義消息的接收者與消息返回的地址;另一 方面,定義尋址信息有助於在發生網絡錯誤或丟失響應的情況下將消息返回給請 求者;最後一套完善的尋址機制使的復雜的交互模式成為可能,如圖2所示:
圖2
在WS-Addressing中,其實就兩個概念:終結點引用 (Endpoint Reference)和SOAP結構的消息信息報頭(Message Information Headers)。如下面的示例表示將一條SOAP 1.2的消息發送到 http://fabrikam123.com/Purchasing。:
<S:Envelope xmlns:S="http://www.w3.org/2002/12/soap-envelope"
終結點引用
xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing" >
<S:Header>
<wsa:ReplyTo>
<wsa:Address>http://business456.com/client1</wsa:Address>< br /> </wsa:ReplyTo>
<wsa:To>http://fabrikam123.com/Purchasing</wsa:To>
<wsa:Action>http://fabrikam123.com/SubmitPO</wsa:Action> </S:Header>
<S:Body>
......
</S:Body>
</S:Envelope>
Web 服務終 結點是一個可以引用的實體、處理器或可以作為 Web 服務消息目標的資源,而 終結點引用傳達了標識或者引用一個 Web 服務終結點所需的信息,它的使用方 式可以有多種:終結點引用適用於傳達訪問 Web 服務終結點所需的信息,也可 以在 Web 服務間往返的各條消息提供地址。如下面的代碼表示了終結點引用的 信息集:
<wsa:EndpointReference>
<wsa:Address>xs:anyURI</wsa:Address>
<wsa:ReferenceProperties>... </wsa:ReferenceProperties> ?
<wsa:ReferenceParameters>... </wsa:ReferenceParameters> ?
<wsa:PortType>xs:QName</wsa:PortType> ?
<wsa:ServiceName PortName="xs:NCName"? >xs:QName</wsa:ServiceName> ?
<wsa:Policies> ... </wsa:Policies>?
<xs:any/>*
</wsa:EndpointReference>
從最簡單的意義上來說,終結點 引用就是一些使用XML元素來包裝的URL,如下面的代碼:
<wsa:myLocation>
<wsa:Address>http://localhost:8887/CalculatorService</wsa:Add ress>
</wsa:myLocation>
這裡wsa:myLocation就是 終結點引用,在它的內部是一個Web服務尋址規范定義的元素,用它來指定當訪 問CalculatorService服務時所用的地址。作為終結點引用模型的一部分,每個 終結點引用都可以包含一些添加額外標識信息的引用參數。
消息信息報 頭
消息信息報頭(Message Information Headers)是Web 服務尋址規范定義 了一些附加的也是標准的SOAP頭,它們用於幫助傳送關於消息的信息,它與終結 點引用不同,消息信息報頭將作為SOAP Head的擴展包含在SOAP消息中,它的信 息集如下所示:
<wsa:To>xs:anyURI</wsa:To> ?
<wsa:From>wsa:EndpointReferenceType</wsa:From> ?
<wsa:ReplyTo>wsa:EndpointReferenceType</wsa:ReplyTo> ?
<wsa:FaultTo>wsa:EndpointReferenceType</wsa:FaultTo> ?
<wsa:Action>xs:anyURI</wsa:Action>
<wsa:MessageID>xs:anyURI</wsa:MessageID> ?
<wsa:RelatesTo RelationshipType="xs:anyURI"? >xs:anyURI</wsa:RelatesTo> *
<wsa:ReferenceParameters>xs:any*</wsa:ReferenceParameters&g t; ?
下面我們對其做一些解釋:
To:表示目標 Web 服務的 URL,當使用端點引用(EPR)時,To 頭應該與 <wsa:Address> 元素具有 相同的值。
ReplyTo:表示來自於Web服務的任何響應都應該被發送給ReplyTo終結點 引用,即消息的發送方並不一定是要接收響應消息的終結點,這和From是有區別 的。
FaultTo:如果消息的響應是SOAP錯誤,那麼這個錯誤應該在 FaultTo頭中發送給終結點引用。
MessageID:用來唯一的識別消息。
Action:對於Action可以這麼理解,當消息發送的服務時,指定如何處 理該消息,更簡單一點,就是希望服務調用哪個方法來處理消息。如下代碼所示 ,希望消息到達服務時,調用Add方法來處理。
<wsa:Action>http://tempuri.org/ICalculator/Add</ wsa:Action>
RelatesTo:RelatesTo常用在響應消息中,用來指示 它與先前知道的消息相關並且定義這種關系的URI。這在請求響應模式中非常關 鍵,尤其是異步消息傳遞中,響應消息的接收方必須能夠將它與原始請求消息相 關聯。
我們把消息信息報頭Message Information Headers與SOAP用圖3 來清晰的表示:
圖3
有關WS-Addressing規范的詳細信息大家可以參考 http://www.w3.org/Submission/ws-addressing/。
分析WCF消息
上面 我介紹了Web服務尋址規范,現在我們截獲一下WCF的消息,來看看它是如何符合 WS-Addressing的。現在編寫一個簡單的WCF服務:
/// <summary>
/// Author: TerryLee
/// Url:http://www.cnblogs.com/terrylee
/// </summary>
[ServiceContract]
public interface ICalculator
{
[OperationContract]
int Add(int x, int y);
}
public class CalculatorService : ICalculator
{
public int Add (int x, int y)
{
return x + y;
}
}
我們可以用跟蹤診斷的方式來截獲到SOAP消息,如下所示,可以 看到這個調用服務過程中,消息報頭中的To地址以及Action,這裡的Action就是 我們在服務中定義的Add方法,以及消息的Body:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<To s:mustUnderstand="1">http://localhost:8887/CalculatorServ ice</To>
<Action s:mustUnderstand="1">http://tempuri.org/ICalculator/Add&l t;/Action>
</s:Header>
<s:Body>
<Add xmlns="http://tempuri.org/">
<x>1</x>
<y>2</y>
</Add>
</s:Body>
</s:Envelope>
結束語
Web服務尋址規范帶來了Web服務世界的尋址標准,它通過定義終結點 引用(Endpoint Reference)和消息信息報頭(Message Information Headers )來提供了一種統一的機制。在下一篇中,我將繼續深入分析WCF中的尋址。