|
今天我们介绍WCF4.0消息路由的实现机制,然后会讲解路由服务的实现过程。
【4】WCF与路由服务:
其实在介绍WCF消息路由的时候,我们前面已经消息介绍了WS-Routing和WS-Address规范。但是这些知识还不够。我们现在来了解一下WCF如何调用一个特定的服务方法的。这也是WCF路由服务涉及到的重要内容。下面我们先来介绍一下WCF服务方法的调用原理。
【4.1】 WCF方法调用的原理:
我们知道,在客户端,我们可以通过代理类来调用一个服务的方法。这其实在背后,WCF框架为我们生成了一个SOAP消息。而这个SOAP消息包含我们要调用服务的必要信息。我们看一下简单的SOAP消息的例子:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService1/GetData</Action>
</s:Header>
<s:Body>
<GetData xmlns="http://tempuri.org/">
<value>1</value>
</GetData>
</s:Body>
</s:Envelope>
这个是默认创建的WCF服务程序的客户端调用的SOAP消息结构。但是这个消息又是如何在服务端调用到特定的方法的呢?
在WCF中,每个服务端点实际上有两个地址:
逻辑地址:逻辑地址(“To”)是 SOAP 消息的目标地址。
物理地址:物理地址(“Via”)是 WCF侦听消息的实际传输特定网络地址。
WCF通道基础结构针对的是物理地址,因为物理地址负责使用特定的传输协议在特定的位置ListenURI接收传入的消息。 WCF调度程序避开了这种联网细节,而是关注将传入消息映射到一个端点,并最终到达方法调用。
【4.2】 WCF消息筛选器:
那么WCF根据什么来实现消息的匹配的呢?这里就要介绍一个重要的概念:消息过滤器。MessageFilter实例负责消息的调度。前面的SOAP中的Action值,是一个消息调度的方式。
当传入消息时,WCF使用消息过滤器器确定匹配端点。我们也可以自己定义消息过滤器器类型。WCF对于自定义消息过滤器器的支持,带来了很大的灵活性。我们可以摆脱传统调度模型,实现SOAP 以外的调度方式 :实现 REST/POX 样式的服务。
每个终结点实际上关联着两个过滤器:
地址过滤器:确定传入消息是否匹配端点的“To”地址和任何必需的地址标头,
契约过滤器:确定它是否匹配端点的契约。
两个筛选器都被调度程序用来确定目标端点。
WCF类型系统定义了6个消息过滤器类型以满足不同的需求,它们是:
XPathMessageFilter 使用 XPath 1.0 表达式来指定匹配的条件,它是实现基于内容路由的核心消息过滤器。
MatchAllMessageFilter 与所有消息相匹配。
MatchNoneMessageFilter 与所有消息都不匹配。
ActionMessageFilter 测试消息操作是否为指定的操作集之一。也就操作匹配。
EndpointAddressMessageFilter 测试消息是否满足指定的终结点地址。
PrefixEndpointAddressMessageFilter 对消息 URI 的前缀进行匹配,只要传入的“To”地址与端点地址有相同的地址前缀(一种松散匹配),将导致两者匹配。
WCF过滤器只是 MessageFilter的子类。MessageFilter 有几个内置实现,包括 EndpointAddressMessageFilter 和 ActionMessageFilter,它们分别作为默认地址和契约过滤器。
EndpointAddressMessageFilter 仅仅将“To”地址与端点地址进行比较,预期它们完全匹配。它也将传入消息中获得的寻址标头和终结点要求的一组寻址标头进行比较。
ActionMessageFilter 将传入的“Action”值和约定上的操作进行比较,再次预期完全匹配。
PrefixEndpointAddressMessageFilter 只要传入的“To”地址与端点地址有相同的地址前缀(一种松散匹配),将导致两者匹配。
MatchAllMessageFilter,它导致所有消息匹配给定端点。
我们可以通过 [ServiceBehavior] 的 AddressFilterMode 属性来选择消息过滤器。使用 PrefixEndpointAddressMessageFilter的例子代码:
[ServiceBehavior(AddressFilterMode=AddressFilterMode.Prefix)]
public class CalculatorService : ISimpleMath, IScientif
【4.3】WCF路由服务类型RoutingService:
WCF4.0实现了一个路由服务类型RoutingService,它可以支持多种消息交换模式的消息路由场景:单向、请求/应答、双工。RoutingService的定义如下:
namespace System.ServiceModel.Routing
{
// Summary:
// Defines the routing service, which is responsible for routing messages between
// endpoints based on filter criteria.
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any, InstanceContextMode = InstanceContextMode.PerSession, UseSynchronizationContext = false, ValidateMustUnderstand = false)]
public sealed class RoutingService : ISimplexDatagramRouter, ISimplexSessionRouter, IRequestReplyRouter, IDuplexSessionRouter
{
}
}
我们注意到RoutingService 类型为了支持不同的消息交换模式,实现了多个契约接口: ISimplexDatagramRouter、
IRequestReplyRouter、IDisposable。为了实现回会话路由,它也实现了ISimplexSessionRouter、IDuplexSessionRouter接口。路由服务会根据消息过滤器的条件在服务终结点之间来转发消息。也就是路由消息。
【5】WCF4.0 路由服务开发过程详解:
了解了WCF路由的一些机制以后,我们就来实现今天的消息路由的Demo。这个程序呢,包含4个部分。客户端、路由服务和2个WCF服务。路由服务的结构图如下所示:

客户端通过basicHttp发送消息到路由服务,路由服务根据消息过滤器设置来转发消息到服务A或者B,但是使用的绑定有所改变,发送给服务A的绑定为WSHttpBinding,而服务B交互使用的绑定为NetTcpBinding。
我们知道这个机制实际上对于SOAP的版本做了改变,但是可以制止完整的消息路由,这里我们使用MEP,也就是请求/应答消息交换模式。消息交换模式在《WCF技术内幕》里做过详细的介绍。
【5.1】服务A和服务B:
这里定义的服务A和服务B,只是两个简单的测试服务,分别暴露的方法为服务A:Hello,而服务B为Bye。
服务A的实现代码如下:
//1.服务契约
[ServiceContract(Namespace = " http://www.cnblogs.com/frank_xl/")]
public interface IWCFServiceA
{
//操作契约
[OperationContract(Action = "SayHello", ReplyAction = "SayHelloAReply")]
string SayHello(string name);
}
//2.服务类,继承接口。实现服务契约定义的操作
public class WCFServiceA : IWCFServiceA
{
//实现接口定义的方法
public string SayHello(string name)
{
Console.WriteLine("Hello! {0},Calling at {1} ...", name,DateTime.Now.ToLongTimeString());
return "Hello ! " + name;
}
}
(责任编辑:admin) |