WCF专题系列(3):深入WCF寻址Part 3—消息过滤引擎
消息筛选器表
消息筛选器表用于存储键-值对,其中筛选器为键,而与筛选器关联的数据为值。筛选器数据可用于指示当消息与筛选器匹配时要采取的操作,筛选器数据的类型是筛选器表类的泛型参数。 筛选器数据可以包含路由规则、会话安全状态、通道上的侦听器等等。所有的消息筛选器都存储在实现了IMessageFilterTable<TFilterData>的表中,如MessageFilterTable<TFilterData>,在它的内部,又有很多个与具体筛选器类型相关的筛选器表,添加筛选器时,会将其放置在包含此类筛选器的内部筛选器表(如果已存在)中。如果不存在此筛选器表,则调用 CreateFilterTable 以分配一个适当类型的新筛选器表,如图3所示:
图3
同时在添加筛选器时,筛选器表会给每个筛选器设置一个默认的优先级。
设置服务的消息筛选器
我们可以通过ServiceBehavior来指定服务所用的消息筛选器,在ServiceBehavior中有一个AddressFilterMode的属性,它用来指定调度程序用于将传入的消息路由到匹配的终结点,由三个选项:
Exact:指示对传入消息的地址执行精确匹配的筛选器,即使用EndpointAddressMessageFilter。
Prefix:指示对传入消息的地址执行最长前缀匹配的筛选器,即使用PrefixEndpointAddressMessageFilter。
Any:指示与传入消息的任意地址相匹配的筛选器,即使用MatchAllMessageFilter。
如下面的代码,指示使用PrefixEndpointAddressMessageFilter作为地址筛选器:
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Prefix)] public class CalculatorService : ICalculator { public int Add(int x, int y) { return x + y; } }
我们可以在Host端输出一下EndpointDispatcher所用的地址筛选器和契约筛选器,如下代码所示:
static void Main(string[] args) { using (ServiceHost calculatorServiceHost = new ServiceHost(typeof(CalculatorService))) { calculatorServiceHost.Opened += delegate { Console.WriteLine("Service begin to listen via the Address:{0}", calculatorServiceHost.BaseAddresses[0].ToString()); }; calculatorServiceHost.Open(); foreach (ChannelDispatcher channelDispatcher in calculatorServiceHost.ChannelDispatchers) { Console.WriteLine(channelDispatcher.BindingName); foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints) { Console.WriteLine(endpointDispatcher.AddressFilter.ToString()); Console.WriteLine(endpointDispatcher.ContractFilter.ToString()); } Console.WriteLine("---------------------------"); } Console.Read(); } }
输出结果如图4所示:
图4
结束语
本文详细介绍了WCF中的消息筛选器,这在某些场景下非常有用,可以根据SOAP消息标头中包含的数据将消息发送到不同的地方处理,这在一定程度上可以摆脱WCF的调度模型。