日期:2012-08-30  浏览次数:20438 次

在运行时使用 UDDI
Karsten Januszewski
Microsoft Corporation
2001 年 12 月

摘要:本文概述了在运行时使用 UDDI,讨论了 UDDI(公共注册表和 UDDI 服务在 Microsoft Windows .NET Server 中提供)如何用作 Web 服务的基础结构以支持客户端应用程序。

目录

  • 简介
  • UDDI 运行时基础结构
  • 示例方案
  • 创建 Web 服务:C# .NET .asmx
  • 使用 Web 服务:C# Windows 窗体 .NET 客户端
  • 其他方案
  • 总结

简介


UDDI(通用说明、发现和集成)通常称为 Web 服务的“黄页”。虽然黄页这一类比对于帮助理解很有用,但它不能完整体现 UDDI 是如何并入基于 Web 服务的软件体系结构中的。黄页类比只涉及 UDDI 的设计时用法,即通过基于关键字、类别或接口的搜索来查找和使用 Web 服务的功能。从设计时角度来看,黄页类比十分准确:就象黄页将企业及其电话号码分类并编成目录一样,UDDI 将提供者及其 Web 服务分类并编成目录。开发人员可以在 UDDI 中查找 WSDL 文件和入口点,然后将这些 Web 服务并入客户端应用程序。
不过,UDDI 不仅仅提供设计时支持。黄页类比并没有提及 UDDI 如何支持运行时。发现过程结束后,UDDI 将扮演一个很重要的角色。在运行时通过编程方式查询 UDDI 这一功能使 UDDI 可以用作构建可靠而稳固的 Web 服务应用程序的基础结构。

UDDI 运行时基础结构


将 Web 服务集成到客户端应用程序中后,需要考虑可能会遇到的问题,其中一个关键问题是无法预测或检测提供 Web 服务的提供者的故障,或者从故障中恢复。如果 Web 服务出现故障,客户端应用程序可以采取什么措施?应用程序如何适当且动态地从失败的 Web 服务调用中恢复?
同样,从 Web 服务提供者的角度看,Web 服务的所有者如何动态更新更改内容?我们需要考虑将 Web 服务移到新服务器的情况。如何将此更改通过有效方式通知到 Web 服务的客户端?所有者如何在运行时分发此信息,而不会导致 Web 服务的所有客户端中断?
在上述情况下,UDDI 在提供基础结构以支持运行时 Web 服务方面能够扮演十分重要的角色。UDDI 通过定义调用规则来解决这些“服务质量”问题,该调用规则包括缓存绑定信息(如 Web 服务的入口点)以及针对此特定实现方式的其他参数。发生故障时,客户端可以发出运行时 UDDI 查询,用最新信息刷新缓存的信息。
上述规定的模式如下:
  1. 在 UDDI 中查找 Web 服务。使用此 Web 服务(以 UDDI tModel 表示)的 WSDL 文件以及入口点和其他配置信息的实现细节,所有这些信息都包含在 UDDI bindingTemplate 中。
  2. 为特定的 Web 服务准备一个客户端应用程序。在客户端应用程序中,缓存 Web 服务的唯一 bindingKey,以便在首次使用该应用程序时,从 UDDI 检索所需的所有信息。
  3. 当应用程序调用远程 Web 服务时,使用从 UDDI Web 注册表获得的缓存数据。
  4. 如果调用失败,则使用 bindingKey 值和对 UDDI 注册表的 get_bindingTemplate API 调用以获取新的绑定信息。
  5. 对新旧信息进行比较:如果不同,则重试失败的调用。如果重试成功,则用新数据替换缓存的数据并存储新数据以便以后调用。不过,如果返回的绑定信息相同,则提供者不进行任何更新,且应用程序将发生错误。同样,如果有新的绑定信息,但调用仍然失败,应用程序也会发生错误。

从 Web 服务提供者的角度来说,提供者应当知道何时可以更新该 Web 服务的 UDDI 项。当 Web 服务的提供者需要将流量重定向到新位置或者需要备份系统时,提供者只需激活备份系统,然后在 UDDI 注册表中更改入口点。此方法称为失败时重试,为客户端提供了一种在运行时从故障中恢复的机制。

示例方案


我们可以看一个示例,以了解此模式的工作原理。此示例方案涉及的是一家虚构公司的方案,该公司需要向其内部部门提供实时销售数据。因此,此 Web 服务不能公开,而只在防火墙内部使用。
首先,我们需要一个 Web 服务。在这种情况下,我们将提供一个非常简单的 Web 服务,它只支持 GetSalesTotalByRange 一种方法,这种方法使客户端能够获取一定日期范围内实时销售数据的瞬态图。
接下来将创建使用此 Web 服务的客户端。我们将客户端配置为可以缓存入口点和 bindingKey 信息,并为客户端设置一种机制,以便在发生故障时从 UDDI 注册表刷新客户端缓存。

创建 Web 服务:C# .NET .asmx


Microsoft .NET 框架大大简化了 Web 服务的编写工作。在本例中,我们将创建一个简单的 Web 服务,它只包含 GetSalesTotalByRange 一种方法,该方法使用两个日期作为输入参数,并返回两个参数。下面是一个实现了此目的的 .asmx 页,SalesReport.asmx:
<%@ WebService Language="c#" Class="SalesReportUSA.SalesReport" %>using System;using System.Web.Services;namespace SalesReportUSA{   [WebService(Namespace="urn:myCompany-com:SalesReport-Interface")]   public class SalesReport : System.Web.Services.WebService   {      [WebMethod]      public double GetSalesTotalByRange ( System.DateTime startDate, System.DateTime endDate )      {         return 5000.00;      }      }} 

此页应添加到虚拟目录中。要使客户端示例工作,请创建一个名为 SalesReportUSA 的虚拟目录 (http://localhost/SalesReportUSA/SalesReport.asmx)。请注意,此 Web 服务始终返回 5000.00 作为返回值。(要是销售报表能够有这样的可预见性就好了!)真实的应用程序应当使用数据库调用来检索此信息。对于本示例,只需要一个硬编码的值。
部署此 Web 服务的下一步是在 UDDI 注册表中注册该服务。此 UDDI 注册表是一个内部 UDDI 服务器,公开此 Web 服务没有什么意义。Microsoft 通过 Microsoft® Windows® .NET Server 提供本地 UDDI 服务。有关此功能的详细信息,请参阅 Windows .NET Server(英文)Web 站点。如果没有安装 Microsoft .NET Server,您可以使用 Microsoft UDDI 软件开发包 (SDK)(英文)在本地计算机上安装 UDDI。
可以通过两种方式在 UDDI 中注册 Web 服务:可以使用 Web 用户界面注册,或者使用 UDDI SDK 通过编程方式注册 Web 服务。SDK 使用起来非常方便,您可以参阅使用 UDDI 的 Web 服务说明和发现专栏中发布的代码示例。无论使用哪一种方法,都需要先将 Web 服务的 WSDL 文件注册为 tModel。UDDI tModel 是 XML 实体,用于表示接口和抽象的元数据,因此,WSDL 文件表示为 tModel。然后,您需要将 Web 服务的入口点注册为 bindingTemplate。UDDI bindingTemplate 是 XML 结构,用于表示有关给定 Web 服务的实现细节。有关 UDDI 架构及其与 WSDL 的关系的详细信息,请参阅 http://www.uddi.org(英文)和 UDDI“最佳实践”文档 Using WSDL in a UDDI Registry 1.05(英文)。
以下是使用 UDDI 服务完成上述步骤后得到的 UDDI bi