本文首发博客园,作者TerryLee,原文地址:WCF专题系列(1):深入WCF寻址Part 1
概述
众所周知,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> </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:Address> </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> ?
下面我们对其做一些解释:
To:表示目标 Web 服务的 URL,当使用端点引用(EPR)时,To 头应该与 <wsa:Address> 元素具有相同的值。
From:表示消息发送方的终结点引用,如果消息接收方需要向发送消息的终结点发送回消息,那么它应该使用这个终结点引用。
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/CalculatorService</To> <Action s:mustUnderstand="1">http://tempuri.org/ICalculator/Add</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中的寻址。
本文首发博客园,作者TerryLee,原文地址:WCF专题系列(1):深入WCF寻址Part 1