WCF 4.0 之 Routing Service
来源:互联网 发布:淘宝店铺装修不能编辑 编辑:程序博客网 时间:2024/05/23 18:52
现在WCF 4.0内置了路由服务——System.ServiceModel.Routing.RoutingService,可以在 System.ServiceModel.Routing.dll 中找到。
比如下面的场景会使用到路由服务:只暴露一个外部公开的 Endpoint 映射到内部的多个的服务上。
路由服务使用的消息筛选器提供常用消息选择功能,例如,终结点的名称、SOAP 操作或消息已发送到的地址或地址前缀。也可以使用AND 条件连接筛选器,这样,仅当消息同时与两个筛选器匹配时,才会将消息路由至某个终结点。此外,还可以通过创建自己的 MessageFilter 实现来创建自定义筛选器。(MSDN:消息筛选器)
下面做一个实例来看看 RoutingService 该如何配置。
1. Console Hosting Request/Reply WCF Service Routing (示例代码下载)
(1) 创建一个普通的Wcf Service Library (使用Console Hosting)
Console Host
- static void Main(string[] args)
- {
- using (var host = new ServiceHost(typeof(WcfSvcLib.Service1)))
- {
- host.Open();
- Console.WriteLine("WcfService1 is started...............");
- Console.Read();
- }
- }
- <system.serviceModel>
- <services>
- <servicename="WcfSvcLib.Service1"behaviorConfiguration="WcfSvcLib.Service1Behavior">
- <host>
- <baseAddresses>
- <addbaseAddress="http://localhost:20000/WcfRoutingServiceTest/Service1/"/>
- </baseAddresses>
- </host>
- <endpointname="WcfService1"address=""binding="wsHttpBinding"contract="WcfSvcLib.IService1">
- <identity>
- <dnsvalue="localhost"/>
- </identity>
- </endpoint>
- <endpointaddress="mex"binding="mexHttpBinding"contract="IMetadataExchange"/>
- </service>
- </services>
- <behaviors>
- <serviceBehaviors>
- <behaviorname="WcfSvcLib.Service1Behavior">
- <serviceMetadatahttpGetEnabled="True"/>
- <serviceDebugincludeExceptionDetailInFaults="False"/>
- </behavior>
- </serviceBehaviors>
- </behaviors>
- </system.serviceModel>
为了测试,Service1 使用的是 PerSession,当 Service1 被第一次调用时,服务端构造一次 Service1 实例。并在之后的调用中保持该 Session。
SetName 将保存一个值,GetName 则取出该值。
- namespace WcfSvcLib
- {
- [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
- public class Service1 : IService1
- {
- private string _name ="";
- public Service1()
- {
- Console.WriteLine("Service1 ctor: " + Guid.NewGuid().ToString());
- }
- public string GetData(int value)
- {
- return string.Format("You entered: {0}", value);
- }
- public void SetName(string name)
- {
- _name = name;
- }
- public string GetName()
- {
- return _name;
- }
- }
- }
首先添加 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 的配置文件,详细参看代码中的注释说明。
- <?xmlversion="1.0"?>
- <configuration>
- <system.web>
- <compilationdebug="true"/>
- </system.web>
- <system.serviceModel>
- <services>
- <!-- 定义 Routing Service 的地址(baseAddress+endpoint address),
- 绑定(wsHttpBinding),契约(System.ServiceModel.Routing.IRequestReplyRouter) -->
- <!-- 注意:Routing Service 的契约必须和被路由服务的模型吻合比如:
- Request/Reply 模式,OneWay 模式,或者是 Duplex 模式。这里是 Request/Reply 模式 -->
- <servicename="System.ServiceModel.Routing.RoutingService"behaviorConfiguration="MyRoutedServBehavior">
- <host>
- <baseAddresses>
- <addbaseAddress="http://localhost:20002/WcfRoutingServiceTest/router"/>
- </baseAddresses>
- </host>
- <endpointaddress="service1"binding="wsHttpBinding"name="MyRoutingEndpoint"contract="System.ServiceModel.Routing.IRequestReplyRouter"/>
- </service>
- </services>
- <!-- 在 serviceBehavior 中加入了 routing 配置节,指明使用的 filterTableName -->
- <behaviors>
- <serviceBehaviors>
- <behaviorname="MyRoutedServBehavior">
- <serviceMetadatahttpGetEnabled="True"/>
- <serviceDebugincludeExceptionDetailInFaults="True"/>
- <routingfilterTableName="ServiceRouterTable"/>
- </behavior>
- </serviceBehaviors>
- </behaviors>
- <routing>
- <!-- filterTable 中配置了 filter 和 client endpoint 的映射关系 -->
- <!-- 注意:当使用 Request/Reply 模型时,filterTable 里不能有多个 Endpoint
- (详细参看:http://msdn.microsoft.com/zh-cn/library/ee816891.aspx 的多播一节)-->
- <filterTables>
- <filterTablename="ServiceRouterTable">
- <addfilterName="ServiceRouter_Filter1"endpointName="WcfService1"/>
- <!--
- <addfilterName="ServiceRouter_Filter2"endpointName="WcfService1"/>
- <addfilterName="ServiceRouter_Filter3"endpointName="WcfService1"/>
- -->
- </filterTable>
- </filterTables>
- <filters>
- <!-- 配置 filter:-->
- <!-- filterType 有:MatchAll, Action, EndpointAddress, EndpointAddressPrefix, EndpointName, XPath, Custom, And-->
- <!-- (1) MatchAll 时,filterData 就无视了,直接转发给真实的 Endpoint -->
- <!-- (2) Action 时,filterData 里填写的内容应该是 "协议://Namespace(注1)/ServiceContractName/OperationContractName" -->
- <!-- (3) EndpointAddress,filterData 里填写的某服务的URL,比如:"http://<主机名>/vdir/s.svc/b"-->
- <!-- (4) EndpointAddressPrefix, 和(3)EndpointAddress类似,顾名思义地址前缀匹配,比如:""http://<主机名>/vdir/s.svc"-->
- <!-- (5) EndpointName, 比写全地址更灵活且不容易出错(service 配置节里的 EndpoingName) -->
- <!-- (6) XPath, 功能较上面更为强大,通过对 soap 消息的 XPath 定义匹配 -->
- <!-- (7) Custom, 自定义过滤器通过继承:CustomAssembly.MyCustomMsgFilter MessageFilter 重写 Match 方法实现 -->
- <!-- (8) And 不直接筛选消息中的值,而是通过它组合两个其他筛选器来创建 AND 条件 -->
- <!-- 例如:<filter name="and1" filterType="And" filter1="address1" filter2="action1" /> -->
- <filtername="ServiceRouter_Filter1"filterType="MatchAll"/>
- <!--
- <filtername="ServiceRouter_Filter2"filterType="Action"filterData="http://tempuri.org/IService1/GetName"/>
- <filtername="ServiceRouter_Filter3"filterType="Action"filterData="http://tempuri.org/IService1/SetName"/>
- -->
- </filters>
- </routing>
- <!-- client 配置节配置了路由服务要转发的真实服务地址 -->
- <client>
- <endpoint
- name="WcfService1"binding="wsHttpBinding"
- address="http://localhost:20000/WcfRoutingServiceTest/Service1/"
- contract="*">
- </endpoint>
- </client>
- </system.serviceModel>
- <startup><supportedRuntimeversion="v4.0"sku=".NETFramework,Version=v4.0"/></startup></configuration>
首先是客户端代理的生成,通过 Wcf Routing Service 好像没有办法能访问到真实服务的wsdl,
因此我的做法是先利用真实服务的wsdl生成代理,然后修改客户端配置文件。
比如这个例子中真实服务地址是:http://localhost:20000/WcfRoutingServiceTest/Service1
Wcf Routing Service的地址是: http://localhost:20002/WcfRoutingServiceTest/router/service1
修改后的客户端配置如下:
- <?xmlversion="1.0"encoding="utf-8"?>
- <configuration>
- <system.serviceModel>
- <client>
- <endpointaddress="http://localhost:20002/WcfRoutingServiceTest/router/service1"
- binding="wsHttpBinding"contract="WcfService1.IService1"name="WcfService1">
- <identity>
- <dnsvalue="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();
- }
- }
运行结果显示,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 文件激活服务的新特性:
- <serviceHostingEnvironmentmultipleSiteBindingsEnabled="true">
- <serviceActivations>
- <addrelativeAddress="RoutingService.svc"
- service="System.ServiceModel.Routing.RoutingService,
- System.ServiceModel.Routing, version=4.0.0.0, Culture=neutral,
- PublicKeyToken=31bf3856ad364e35" />
- </serviceActivations>
- </serviceHostingEnvironment>
完整配置如下:
- <?xmlversion="1.0"?>
- <configuration>
- <system.web>
- <compilationdebug="true"targetFramework="4.0"/>
- </system.web>
- <system.serviceModel>
- <bindings>
- <wsHttpBinding>
- <bindingname="NonSecurityBinding">
- <securitymode="None"/>
- </binding>
- </wsHttpBinding>
- </bindings>
- <serviceHostingEnvironmentmultipleSiteBindingsEnabled="true">
- <serviceActivations>
- <addrelativeAddress="RoutingService.svc"
- service="System.ServiceModel.Routing.RoutingService,
- System.ServiceModel.Routing, version=4.0.0.0, Culture=neutral,
- PublicKeyToken=31bf3856ad364e35" />
- </serviceActivations>
- </serviceHostingEnvironment>
- <services>
- <servicename="System.ServiceModel.Routing.RoutingService"behaviorConfiguration="RoutingSvcBehaviorConfig">
- <endpointaddress="service1"binding="basicHttpBinding" name="service1Endpoint"contract="System.ServiceModel.Routing.IRequestReplyRouter"/>
- <endpointaddress="service2"binding="basicHttpBinding" name="service2Endpoint"contract="System.ServiceModel.Routing.IRequestReplyRouter"/>
- </service>
- </services>
- <behaviors>
- <serviceBehaviors>
- <behaviorname="RoutingSvcBehaviorConfig">
- <serviceMetadatahttpGetEnabled="True"/>
- <serviceDebugincludeExceptionDetailInFaults="True"/>
- <routingfilterTableName="ServiceRoutingTable"soapProcessingEnabled="true"/>
- </behavior>
- </serviceBehaviors>
- </behaviors>
- <routing>
- <filterTables>
- <!-- endprointName 对应上面 service/endpoint/name -->
- <filterTablename="ServiceRoutingTable">
- <addfilterName="Service1Filter"endpointName="WcfService1"/>
- <addfilterName="Service2Filter"endpointName="WcfService2"/>
- </filterTable>
- </filterTables>
- <filters>
- <filtername="Service1Filter"filterType="EndpointName"filterData="service1Endpoint"/>
- <filtername="Service2Filter"filterType="EndpointName"filterData="service2Endpoint"/>
- </filters>
- </routing>
- <client>
- <endpointname="WcfService1"binding="basicHttpBinding"address="http://localhost:20002/Service1.svc"contract="*"/>
- <endpointname="WcfService2"binding="basicHttpBinding"address="http://localhost:20003/Service2.svc"contract="*"/>
- </client>
- </system.serviceModel>
- <system.webServer>
- <modulesrunAllManagedModulesForAllRequests="true"/>
- </system.webServer>
- </configuration>
客户端配置文件
- <?xmlversion="1.0"?>
- <configuration>
- <system.serviceModel>
- <bindings>
- <basicHttpBinding>
- <bindingname="BasicHttpBinding_IService1"/>
- <bindingname="BasicHttpBinding_IService2"/>
- <bindingname="service1Endpoint"/>
- </basicHttpBinding>
- </bindings>
- <client>
- <endpointaddress="http://localhost:20001/RoutingService.svc/service1"
- binding="basicHttpBinding"bindingConfiguration="BasicHttpBinding_IService1"
- contract="WcfService1.IService1"name="service1Endpoint"/>
- <endpointaddress="http://localhost:20001/RoutingService.svc/service2"
- binding="basicHttpBinding"bindingConfiguration="BasicHttpBinding_IService2"
- contract="WcfService2.IService2"name="service2Endpoint"/>
- </client>
- </system.serviceModel>
- <startup><supportedRuntimeversion="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();
- }
----------------------------- 分割线 ----------------------------
http://msdn.microsoft.com/zh-cn/library/ee517419.aspx
http://blogs.profitbase.com/tsenn/?p=23
http://msdn.microsoft.com/zh-cn/library/ee517425.aspx
- WCF 4.0 之 Routing Service
- WCF 之 服务契约(Service Contract)
- 使用WCF 4.0 构建 REST Service
- 使用WCF 4.0 构建 REST Service
- RabbitMq之Routing,Topics
- RabbitMQ之Routing
- [原创]WCF后续之旅(3): WCF Service Mode Layer 的中枢—Dispatcher
- WCF后续之旅(3): WCF Service Mode Layer 的中枢—Dispatcher
- WCF4.0 —— Routing Service
- [WCF] Service contract
- WCF Service Configuration Editor
- WCF Data Service QuickStart
- WCF service performance issue
- WCF Service Binding Explained
- WCF Service Reference error
- wcf/web service 编码
- WCF Data Service 使用
- WCF Data Service
- opencv(arm移植总结)
- 会员管理系统分析
- java 运行时 Exception in thread "main" java.lang.NoClassDefFoundError
- 头真的好疼,怎么才能不去想,谁能告诉我。
- SPD工作流设计器到暂停时间无法触发的分析解决办法
- WCF 4.0 之 Routing Service
- D3D学习三:矩阵Matrices
- awk用法小结
- 学习笔记:关注C++设计模式之Singleton模式
- JQuery Chapter7 JQuery插件的使用和开发(包含了AjaxPart2)
- VS2005断点失效的问题
- DOS 命令大全(珍藏版)
- Cannot cast from ActionForm to XXForm 解决办法
- File,FileInputStream,FileReader,InputStreamReader,BufferedReader 的使用和区别