现在WCF 4.0内置了路由服务——System.ServiceModel.Routing.RoutingService,可以在 System.ServiceModel.Routing.dll 中找到。
比如下面的场景会使用到路由服务:只暴露一个外部公开的 Endpoint 映射到内部的多个的服务上。
路由服务使用的消息筛选器提供常用消息选择功能,例如,终结点的名称、SOAP 操作或消息已发送到的地址或地址前缀。也可以使用 AND 条件连接筛选器,这样,仅当消息同时与两个筛选器匹配时,才会将消息路由至某个终结点。此外,还可以通过创建自己的 MessageFilter 实现来创建自定义筛选器。(MSDN:消息筛选器)
OK,废话少说下面做一个实例来看看 RoutingService 该如何配置。
1. Console Hosting Request/Reply WCF Service Routing (示例代码下载)
(1) 创建一个普通的Wcf Service Library (使用Console Hosting)
Console Host
<system.serviceModel> <services> <service name="WcfSvcLib.Service1" behaviorConfiguration="WcfSvcLib.Service1Behavior"> <host> <baseAddresses> <add baseAddress="http://localhost:20000/WcfRoutingServiceTest/Service1/"/> </baseAddresses> </host> <endpoint name="WcfService1" address="" binding="wsHttpBinding" contract="WcfSvcLib.IService1"> <identity> <dns value="localhost"/> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="WcfSvcLib.Service1Behavior"> <serviceMetadata httpGetEnabled="True"/> <serviceDebug includeExceptionDetailInFaults="False"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
为了测试,Service1 使用的是 PerSession,当 Service1 被第一次调用时,服务端构造一次 Service1 实例。并在之后的调用中保持该 Session。
SetName 将保存一个值,GetName 则取出该值。
首先添加System.ServiceModel.Routing.dll, using System.ServiceModel.Routing;
static void Main(string[] args) { using (var host = new ServiceHost(typeof(RoutingService))) { try { host.Open(); Console.WriteLine("RoutingService is started..............."); Console.Read(); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.Read(); } }
重点在于 RoutingService 的配置文件,详细参看代码中的注释说明。
首先是客户端代理的生成,通过 Wcf Routing Service 好像没有办法能访问到真实服务的wsdl,
因此我的做法是先利用真实服务的wsdl生成代理,然后修改客户端配置文件。
比如这个例子中真实服务地址是:http://localhost:20000/WcfRoutingServiceTest/Service1
Wcf Routing Service的地址是: http://localhost:20002/WcfRoutingServiceTest/router/service1
修改后的客户端配置如下:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <client> <endpoint address="http://localhost:20002/WcfRoutingServiceTest/router/service1" binding="wsHttpBinding" contract="WcfService1.IService1" name="WcfService1" > <identity> <dns value="localhost" /> </identity> </endpoint> </client> </system.serviceModel> </configuration> 客户端调用:
static void Main(string[] args) { using (var client = new WcfService1.Service1Client()) { var result = client.GetData(300); Console.WriteLine(result); result = client.GetData(200); Console.WriteLine(result); result = client.GetData(100); Console.WriteLine(result); client.SetName("test"); Console.WriteLine(client.GetName()); Console.Read(); } } (4) 运行
运行结果显示,client -> Routing Service -> Wcf Service1 注意当PerSession时,如果在RoutingService 每个filter 对于 WcfService1 都是独立的Session。
http://topic.csdn.net/u/20111005/15/69a4c0b8-63ab-4528-a520-6a8568ee17d3.html
----------------------------- 分割线 ----------------------------
2. IIS Hosting Request/Reply WCF Service Routing(示例代码下载)
当使用IIS Hosting时,我们创建的 WCF 工程模板就需要改为 Wcf Service Application了。下面介绍如何配置 Wcf Service Application 中的 Routing Service
这次需要实现的是在一个 Routing Service 中路由多个不同地址的 Wcf Service (如文章开头的图片所示)
(1) Solution Overview
其中:
WcfRoutingService :http://localhost:20001/RoutingService.svc
WcfService1 : http://localhost:20002/Service1.svc
WcfService2: http://localhost:20003/Service1.svc
(2) 配置 WcfRoutingService
因为 WcfRoutingService 里没有任何 svc 文件,这里利用了 WCF 4.0 的无 svc 文件激活服务的新特性:
完整配置如下:
<?xml version="1.0"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.serviceModel> <bindings> <wsHttpBinding> <binding name="NonSecurityBinding"> <security mode="None" /> </binding> </wsHttpBinding> </bindings> <serviceHostingEnvironment multipleSiteBindingsEnabled="true"> <serviceActivations> <add relativeAddress="RoutingService.svc" service="System.ServiceModel.Routing.RoutingService, System.ServiceModel.Routing, version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /> </serviceActivations> </serviceHostingEnvironment> <services> <service name="System.ServiceModel.Routing.RoutingService" behaviorConfiguration="RoutingSvcBehaviorConfig"> <endpoint address="service1" binding="basicHttpBinding" name="service1Endpoint" contract="System.ServiceModel.Routing.IRequestReplyRouter"/> <endpoint address="service2" binding="basicHttpBinding" name="service2Endpoint" contract="System.ServiceModel.Routing.IRequestReplyRouter"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="RoutingSvcBehaviorConfig"> <serviceMetadata httpGetEnabled="True"/> <serviceDebug includeExceptionDetailInFaults="True"/> <routing filterTableName="ServiceRoutingTable" soapProcessingEnabled="true" /> </behavior> </serviceBehaviors> </behaviors> <routing> <filterTables> <!-- endprointName 对应上面 service/endpoint/name --> <filterTable name="ServiceRoutingTable"> <add filterName="Service1Filter" endpointName="WcfService1" /> <add filterName="Service2Filter" endpointName="WcfService2" /> </filterTable> </filterTables> <filters> <filter name="Service1Filter" filterType="EndpointName" filterData="service1Endpoint" /> <filter name="Service2Filter" filterType="EndpointName" filterData="service2Endpoint" /> </filters> </routing> <client> <endpoint name="WcfService1" binding="basicHttpBinding" address="http://localhost:20002/Service1.svc" contract="*" /> <endpoint name="WcfService2" binding="basicHttpBinding" address="http://localhost:20003/Service2.svc" contract="*" /> </client> </system.serviceModel> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> </system.webServer> </configuration> (3) 创建客户端应用
客户端配置文件
<?xml version="1.0"?> <configuration> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IService1" /> <binding name="BasicHttpBinding_IService2" /> <binding name="service1Endpoint" /> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost:20001/RoutingService.svc/service1" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="WcfService1.IService1" name="service1Endpoint" /> <endpoint address="http://localhost:20001/RoutingService.svc/service2" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService2" contract="WcfService2.IService2" name="service2Endpoint" /> </client> </system.serviceModel> <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration> 调用
static void Main(string[] args) { // Test for WcfService1 using (var service1client = new WcfService1.Service1Client("service1Endpoint")) { var result = service1client.GetData(300); Console.WriteLine(result); } // Test for WcfService2 using (var service2client = new WcfService2.Service2Client("service2Endpoint")) { var result = service2client.GetData(100); Console.WriteLine(result); } Console.Read(); } (4) 运行
----------------------------- 分割线 ----------------------------
http://msdn.microsoft.com/zh-cn/library/ee517419.aspx