|
服务B的实现代码如下: //1.服务契约
[ServiceContract(Namespace = "http://www.cnblogs.com/frank_xl/")] public interface IWCFServiceB { //操作契约 [OperationContract(Action = "SayBye", ReplyAction = "SayByeReply")] string SayBye(string name); } //2.服务类,继承接口。实现服务契约定义的操作 public class WCFServiceB : IWCFServiceB { //实现接口定义的方法 public string SayBye(string name) { Console.WriteLine("Bye! {0},Calling at {1} ...", name,DateTime.Now.ToLongTimeString()); return "Bye ! " + name; } } 当然实际的项目,可以定义更为复杂的服务契约和数据契约。这里为了简单,只定义了两个服务操作。服务的托管也是Console控制台宿主托管。便于演示。 【5.2】路由服务:
路由服务的实现代码也是比较简单,也是基于Console控制台宿主托管,这里我们要实例化一个服务Host的实例。代码如下:
using (ServiceHost host = new ServiceHost(typeof(RoutingService)))
{ ////判断是否以及打开连接,如果尚未打开,就打开侦听端口 if (host.State != CommunicationState.Opening) host.Open(); //显示运行状态 } 和普通的WCF服务托管没有区别。这里比较难的部分在于消息过滤器的设置。这里我们直接使用配置文件时下,当然你也可以使用C#代码来进行配置。这里我们首先要配置一下服务A和B的地址,因为路由服务要使用这个地址来转发消息: <client>
<endpoint name="EndPointA" address="http://localhost:9001/WCFServiceA" binding="wsHttpBinding" bindingConfiguration="WSConfig" contract="*" /> <endpoint name="EndPointB" bindingConfiguration="netTcpConfig" address="net.tcp://localhost:9002/WCFServiceB" binding="netTcpBinding" contract="*" /> </client> 另外就是启用消息过滤器,这里我们使用的是基于Action的路由方式,当然也可以使用其它的消息过滤器。这里可以直接在配置文件里配置: <routing>
<filters> <filter name="MatchA" filterType="Action" filterData="SayHello" /> <filter name="MatchB" filterType="Action" filterData="SayBye" /> </filters> <filterTables> <filterTable name="WCFRoutingTable"> <add filterName="MatchA" endpointName="EndPointA" /> <add filterName="MatchB" endpointName="EndPointB" /> </filterTable> </filterTables> </routing> 这里配置了消息终结点和SOAP Action之间的对应关系,我们可以从过滤器表filterTable设置这个对应关系。配置完消息过滤器以后,我们还需要在服务行为节点里使用这个filterTable。配置信息如下: <serviceBehaviors>
<behavior name="ServiceBehavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/> <routing filterTableName="WCFRoutingTable" /> </behavior> </serviceBehaviors> 关于路由消息的配置已经基本完成,现在我们还需要为客户端暴露一个可以调用的路由服务的地址。这个终结点地址就是客户端要发送的消息的地址。路由服务的配置也很简单: <services>
<service behaviorConfiguration="ServiceBehavior" name="System.ServiceModel.Routing.RoutingService"> <host> <baseAddresses> <add baseAddress="http://localhost:8001/"/> </baseAddresses> </host> <endpoint address="WCFRoutingService" binding="basicHttpBinding" name="requestReplyEndpoint" contract="System.ServiceModel.Routing.IRequestReplyRouter" /> </service> </services> 我们这里要注意路由服务使用的契约System.ServiceModel.Routing.IRequestReplyRouter和服务名称System.ServiceModel.Routing.RoutingService。 【5.3】客户端:
为了演示方便,我们这里的客户端使用ChannelFactory直接创建客户端代理,与服务进行通信。这里指的注意的地方就是关于路由服务地址的配置。因为客户端都向同一个路由服务的地址来发送消息。但是如何区分不同的服务A和B呢。这里就需要作出配置。这里是通过契约不同来指定最后的服务A或者是B的。
<system.serviceModel>
<client> <endpoint name="WCFServiceA" address="http://localhost:8001/WCFRoutingService" binding="basicHttpBinding" contract="WCFServiceA.IWCFServiceA"/> <endpoint name="WCFServiceB" address="http://localhost:8001/WCFRoutingService" binding="basicHttpBinding" contract="WCFServiceB.IWCFServiceB"/> </client> </system.serviceModel> 当然这些都可以通过代码来进行设置。 【5.4】运行结果:
客户端分别通过路由服务调用了服务A和服务B,代码如下:
IWCFServiceA channelA = new ChannelFactory<IWCFServiceA>("WCFServiceA").CreateChannel();
result = channelA.SayHello("A"); Console.WriteLine("Service A:{0} !", result); IWCFServiceB channelB = new ChannelFactory<IWCFServiceB>("WCFServiceB").CreateChannel(); result = channelB.SayBye("B"); Console.WriteLine("Service B:{0} !", result); 启动程序以后,我们可以看到各个控制台的输出信息: ![]() 这里客户端,我们首先通过路由服务,调用了服务A,服务A返回结果给客户端。并且打印到控制台窗口。 客户端又通过路由服务调用了服务B,服务B返回结果给A。并且打印到控制台窗口。
两次的调用成功。由于篇幅有限,这里没有做出更多的测试。大家也可以对于单向和双工消息交换模式做出测试。
【6】总结:
WCF4.0路由服务的内容就到此结束。
(1)消息路由不是一个新的概念,其实很多平台或者系统都实现了对于消息路由的支持,WCF路由服务也是对于已有WS-Address规范的实现。这是消息路由的本质。
(2)WCF框架为了实现基于不同机制的消息路由,提供了多种消息过滤器类型来满足要求,我们也可以定义自己的消息过滤器,来实现消息的调度。
(3)如果你想实现基于消息内容的路由,也就是content-based routing,就需要借助于Xpath消息过滤器,来根据消息的内容来分析消息路由的信息,进行基于内容的路由功能。
(4)以上就是全部的WCF消息路由的全部内容,下面给出本次课程的代码供大家参考。
|







骆驼户外男 真皮磨砂日常休闲鞋 低帮 2011秋冬新款 专柜正品特价