中间路由器
此示例演示如何实现一个服务,该服务在客户端可能无法直接访问服务的网络配置中提供有用的基本路由功能。此示例不是一个具有多种功能的高效、可伸缩的路由器的示例。
提示
本主题的末尾介绍了此示例的设置过程和生成说明。
在涉及 SOAP 中介的典型通信方案中,客户端发送的消息在到达最终目的地之前会遍历一个或多个其他服务 - 实际处理消息并提供响应(如果需要)的服务。SOAP 中介对通过它传递的消息执行各种操作。例如,缓存中介可以向消息返回缓存的响应,从而缓解服务再次处理请求的压力。负载平衡中介可以使用循环算法将消息转发给众多可能的服务之一。架构验证中介只转发完全符合协定的 XSD 和其他可能的协议的消息。为此示例开发的中介负责根据消息头和内容将消息路由到相应的服务。
有关 SOAP 消息的更多信息,请参见 XML Web Service Wire Formats。
在此示例中,部署了两个应用程序服务以处理客户端请求 - 一个计算器服务和一个回送服务。只能从内部网络访问服务的应用程序终结点。可以公共访问服务的元数据交换 (MEX) 终结点。SOAP 路由器是内部网络的一部分,来自内部网络外部的所有应用程序请求都必须通过该路由器。
客户端是通过对两个服务运行Service Model Metadata Utility Tool (Svcutil.exe) 而创建的,以便在 Svcutil.exe 将第二个服务的配置信息合并到针对第一个服务运行 Svcutil.exe 时创建的现有配置文件中时,生成两个代码文件(每个服务一个客户端)和一个配置文件。每个服务提供的 Web 服务描述语言 (WSDL) 包含 SOAP 中介的地址,而不是实际服务的地址。这样使客户端无需修改配置文件或无需知道 SOAP 中介的地址。
此外,此示例中的路由器服务配置了两个终结点 - 一个使用针对 SOAP 1.2 的 HTTP 侦听采用文本编码的消息,另一个使用针对 SOAP 1.2 的 TCP 侦听采用二进制编码的消息。每个应用程序服务的 WSDL 均使用路由器上的正确终结点地址。还在配置文件的 appSettings 一节中为路由器提供包含以下属性的路由信息:
- prefixes 和 namespaces - 用于更新 WCF 中的默认 XmlNamespaceManager,使其可以解析路由器 XPaths 中的前缀。
- xpath 和 epr - 用于将路由条目添加到将 XPaths 映射到 EPRs 的路由表中。
路由器使用 XpathMessageFilterTable (XPathFilterTable<T>) 类,其中“T”是一个 EndpointAddress,用于存储用户提供的路由条目。当消息到达后,路由器调用 MatchMultiple
方法传入一个 Message 实例,并检索要将消息转发到的 EndpointAddress。
EchoService
和 CalculatorService
都使用 ListenUri 属性来设置终结点侦听的 URI。终结点声明内提供的地址是能够转发服务消息的路由器终结点的地址。这是出现在服务的 WSDL 中的地址,并且是与每个传入消息的 WS-Addressing To 头相匹配的地址。但是,ListenUri 属性提供的地址是终结点的实际物理侦听地址,只供传输使用。
WCF 提供了另一个行为 - ClientViaBehavior 通道行为,该行为通常在 SOAP 中介方案中使用,在此示例中没有使用。客户端使用 ClientViaBehavior 来指定应为其创建传输通道的 URI。如果客户端终结点上的行为集合中存在此类行为,则传输会使用其提供的 URI,而堆栈中的所有其他通道层使用在 ChannelFactory 构造时提供的 EndpointAddress。此 EndpointAddress 也将变为 WS-Addressing To 头。下面的示例代码演示如何使用此行为。
ChannelFactory<IContract> factory = new ChannelFactory<IContract>(new EndpointAddress("http://hostname/service"));
factory.Endpoint.Behaviors.Add(new ClientViaBehavior(new Uri("http://hostname/intermediary")));
IContract channel = factory.CreateChannel();
另一个用于 SOAP 中介的 WCF 功能是 AddressFilter 属性。AddressFilter 由 WCF 用来只接受符合特定筛选器的消息。如果服务协定的方法使用“*”作为 Action,则只检查地址。此示例没有使用此功能,因为地址永远是正确的。路由器接受客户端的消息是因为 To 头与其终结点地址相匹配,服务接受转发给它们的消息是因为 To 头与其终结点的逻辑地址相匹配。
此示例的 Contracts.cs 文件定义了以下四个接口,每个传输模式一个接口:
ISimplexDatagramRouter
. 必须使用此接口接受简单数据报通道上的消息。如果需要单向 HTTP 通道或单向 TCP 和 NamedPipe 通道上的消息,请使用此接口添加一个终结点。IRequestReplyDatagramRouter
. 必须使用此接口接受请求-回复数据报通道上的消息。此接口可用于双向 HTTP 通道上的消息。ISimplexSessionRouter
. 此接口必须接受简单会话通道上的消息。此接口可用于简单 TCP 和简单 NamedPipe 通道。IDuplexSessionRouter
. 此接口用于双工会话通道。此接口可用于双工 TCP 和双工 NamedPipe 通道。
RouterBinding
提供了 WCF 绑定的一个示例,您可以创建该绑定以支持您的 SOAP 中介。它允许您指定此方案中需要的最常见设置,并确保只添加那些确实需要的绑定元素。此外,还演示了基本配置支持。
此示例没有使用 Web 承载,因为它依赖于非 HTTP 传输。当前只有 Windows Vista 和 IIS 7.0 提供 TCP 激活。
运行示例时,操作请求和响应将显示在客户端控制台窗口中。在客户端窗口中按 Enter 可以关闭客户端。
Echo("Is anyone there?") returned: Is anyone there?
Add(5) returned: 5
Add(-3) returned: 2
设置、生成和运行示例
若要生成 C#、C++ 或 Visual Basic .NET 版本的解决方案,请按照生成 Windows Communication Foundation 示例中的说明进行操作。
若要用单一计算机配置或跨计算机配置来运行示例,请按照运行 Windows Communication Foundation 示例中的说明进行操作,但存在以下例外。
- 在单一计算机和跨计算机配置中,需要四个项目和四个可执行文件 - 一个用于客户端,一个用于 SOAP 路由器,另外两个分别用于每个应用程序服务。
- 在跨计算机配置中,必须对四个配置文件进行以下更改。
必须更改CalculatorService
和EchoService
的 App.config 文件的第 21 行。必须用中介的真实主机名替换 localhost 主机名。
必须更改路由器的 App.config 文件的第 15 行。其中的两个地址(用“|”分隔)必须分别更改为EchoService
和CalculatorService
的主机名。
必须更改客户端的 App.config 文件的第 5 行和第 7 行。必须用中介的真实主机名替换 localhost 主机名。
还可以对两个应用程序服务使用Service Model Metadata Utility Tool (Svcutil.exe)(当它们更新为使用正确的地址后)并重新生成 App.config 文件。
在启动客户端之前,请确保
Router
、EchoService
和CalculatorService
都在运行。三个服务都输出它们在启动时侦听的终结点地址。提示
EchoService 和 CalculatorService 的应用程序终结点使用路由器的地址。
运行客户端。客户端首先联系
EchoService
,然后联系CalculatorService
。Router
在两个方向都输出它所转发的消息的 WS-Addressing 操作。提示
如果 Client.exe 和 Router.exe 在不同的计算机上,请在 Client.exe.config 中取消注释 <identity/> 一节,并将用户主体名称设置为正在运行 Router.exe 的用户的主体名称。
Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.