【编者按】:网学网ASP.net为您提供通过复选框路由到 XML Web Services 参考,解决您在通过复选框路由到 XML Web Services 学习中工作中的难题,参考学习。
另一个可以自定义的区域包括客户端激活对象的生存期管理,如下例所示:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="SingleCall" type="SCTrans.SCTransSQL, SCTrans,
Version=0.0.0.0, Culture=neutral,
PublicKeyToken=9c6052078b454cee"
objectUri="SCTrans.SCTransSQL.soap" />
<activated type="SCTrans.SCTransSQL, SCTrans" />
</service>
<lifetime leaseTime="30S" renewOnCallTime="30S" />
</application>
</system.runtime.remoting>
</configuration>
在 web.config 文件中添加的突出显示的行,将此 IIS VRoot 中的客户端激活对象的生存期从 6 分钟更改为 30 秒。如果把 wellknown 元素的 SingleCall 属性更改为 Singleton,则激活行为会更改为将所有传入的方法调用都路由到一个组件,而不是原来的对于每个方法调用都激活一个新组件。
.NET Remoting(类似 .NET 框架的其余部分)支持垃圾回收,而不支持引用计数。这意味着在某些情况下,使用 COM+ Web 服务和 DCOM 时,非托管事务 COM+ 组件的行为方式将有所不同。对于通过 WKO 单一调用发布的事务方法,调用 SetComplete 或选择自动完成(通过选择组件方法属性页的“返回此方法时自动停用该对象”复选框)是极其重要的,这是因为组件在进行垃圾回收前不能被释放。使用 DCOM 时,引用计数通常会导致在释放组件时提交或放弃事务,即使此法则被忽略。移动到 COM+ Web 服务环境时,在垃圾回收环境中,事务超时之前这是不能保证的。如果调用 SetComplete 失败或将方法配置为自动完成失败,则证明其自身的间歇无法提交事务,因为组件被作为垃圾回收之前事务已超时。
设计时应注意的事项
在 COM+ Web 服务中,如果选择了 Uses SOAP 复选框(使用组件服务管理工具),将在 IIS 虚拟根上提供两种不同的激活模型:WKO 和 CAO。哪一种模型更好?用户应该使用哪一种呢?
WKO 单一调用激活模型看起来似乎颇为费事。每种方法调用都需要创建一个新组件,完成方法调用后,再将组件发送到内存回收器。但是,如果特别注重性能并且只能使用 WKO 处理业务时,缓冲的 ServicedComponents 或缓冲的非托管 C++ 组件可以大大缓解单一调用激活的过程。使用缓冲的组件时,WKO 激活将从缓冲池中检索对象,完成调用,然后将对象返回到缓冲池。此协议的无状态性质和缓冲池的使用提高了增加扩展性的可能。在不缓冲对象的 WKO 单一调用中,对象的生命期仅限于调用过程。
另一方面,CAO 提供了服务器上单一激活的性能优势,还可以与某个组件的单一实例继续进行通信。通过从客户端向服务器进行多方法调用可以避免激活的缺点。如果服务器组件(ServicedComponent 或非托管 C++ 组件)被缓冲,则将从缓冲池中检索对象,然后在完成方法调用时将对象返回到缓冲池。如果对象没有被缓冲,则对象生命期取决于 web.config 文件中指定的租用生命期,或由组件自身编程设置。生命期是很重要的,因为直到生命期到期时垃圾回收器才会为组件释放内存。在高容量的 CAO 配置中,这会影响开发人员的某些设计决定。
更进一步
如果您只是希望发布或使用应用了 COM+ Web 服务的 Web 服务,您可以到此为止。但是,如果您希望自定义、扩展或简单了解使用的流程,请继续阅读下面的内容。下面的信息不是使用此项功能所必需的,但是如果您希望手动扩展一些功能,这些信息可能会非常有用。COM+ Web 服务是一个简单的包装程序,通过由 .NET Remoting 提供的一套相当丰富的服务,开发人员或管理员可以轻松地对其进行扩展。
服务器 IIS 虚拟根
为使用此功能,并没有在 .NET Remoting 中添加隐藏挂钩,而是编写了 COM+ 代码以进行必要配置,将 COM+ 端点发布为 IIS 虚拟根。在服务器上,这包括向服务器创建物理目录作为虚拟根,以及生成 web.config 文件,以便通过 Remoting 来访问组件。如果是非托管组件(Visual C++ 或 Visual Basic 6.0),也会生成代理元数据,以便 Remoting 可以访问组件。如果 Windows XP 系统目录是 c:\windows,则服务器配置文件和生成的所有元数据都将存储在以下目录树中:
C:\windows\system32\com\SoapVRoots\vrootname
当在服务器上发布 SOAP 端点时,以下生成的文件将被放入此目录中:
web.config: VRoot 的基本 Remoting 配置文件,包含许多选项,可供开发人员或系统管理员添加或编辑,以调整 Remoting 的性能和安全性。
default.disco: 如果您正在开发托管代码客户端,可与 Visual Studio .NET 一起使用此文件,来生成对已发布的 Web 服务的引用。如果您的业务伙伴希望在企业外联网上开发自己的客户端,这会特别有用。
default.aspx: 简单的 Microsoft ASP.NET 页,可以将每一组件发布为超链接。
上述所有文件都是默认生成的。如果您希望删除其中某些功能,只需编辑或删除相应的文件。(但是,如果删除了 web.config 文件,来自 IIS 虚拟根的所有 SOAP 发布都会停止。)
所有生成的元数据都被放入以下目录以及 GAC 中:
C:\windows\system32\com\SoapVRoots\vrootname\bin
在 .NET Remoting 中,bin 目录是一个很特殊的位置。当 HTTP 请求进入 IIS 时,将在此目录中搜索程序集,因此在许多情况下,bin 目录中的发布是唯一必要的步骤。但是,在发布 SOAP 端点时,生成的程序集也被放入 GAC,这是因为虚拟根的程序集解决方案的范围仅限于 bin 目录和 GAC。如果您的代码在同一台计算机上从一个虚拟根向另一个传递引用,除非程序集在 GAC 中,否则目标虚拟根中的引用解决方案将会失败。如果您正在使用所生成的用于非托管 Visual Basic 6.0 或 Visual C++ 组件的元数据,如果没有传递引用,则可以从 GAC 中删除所生成的程序集。
此版本的 .NET 框架需要特别注意的一点是:如果加载了程序集,并且使用 System.Reflection 来访问程序集文件,则文件将在内存中锁定,直到进程结束。动态生成 WSDL 以便生成代理时,将使用反射,因此对于将由客户端进程访问的活动 IIS 虚拟根来说,可以锁定程序集文件。这在运营环境中不会产生问题,但是对于经常更改组件的开发人员来说,应该牢记这一点。
如果您正在使用带有 COM+ Web 服务的 ServicedComponents,此时也需要将程序集放在 GAC 中,除非您最初将程序集放在了 bin 目录中,并且运行了针对该目录中程序集的 regsvcs.exe。如果已经加载 Microsoft .NET 框架 SDK,您可以使用 gacutil.exe 命令行实用程序,将 ServicedComponent 放入 GAC 中;如果安装了内置 .NET 框架的 Windows .NET Server,或者在 Windows XP 计算机上加载了可重新分发的 .NET 框架,可以使用 Microsoft .NET 框架配置用户界面(可从 Administrative Tools 菜单访问),将程序集添加到 GAC 中。
此外,使用 Windows XP 或 Windows .NET Server 时,请确保已安装并配置了 IIS,以提供 ASP.NET 应用程序服务。这些设置对于提供使用 SOAP 所必需的动态内容是必需的。
生成的代理程序集缓存
对于要通过 .NET Remoting 发布为 SOAP 端点的非托管 COM+ 组件,需要生成代理,使非托管组件可用于 .NET 框架。这可以通过编程执行与 tlbimp.exe(用于将非托管 COM+ 类型库转换为代理元数据程序集的 .NET 框架 SDK 工具)相同的步骤来完成。但是,要通过 SOAP 成功激活客户端,客户端和服务器计算机必须共享相同加强名称的签名元数据代理。因此,当生成用于非托管 COM+ 组件的托管代理程序集时,还会生成加强名称关键字,并用于签名代理程序集。
加强名称关键字只能生成一次,并且在非托管 COM+ 组件中没有加强名称关键字的概念。也就是说,如果多次生成代理,则可以创建不同的加强名称关键字。这会为同一非托管 COM+ 组件创建不同的托管标识,要避免这种情况,请将所有为非托管 COM+ 组件生成的代理程序集写入以下 SoapCache 目录中:
C:\windows\system32\com\SoapCache\componentdirectory\proxymetdata.dll
其中 componentdirectory 的格式应为:
ATLTrans.dll_40960_2001_6_27_15_4_16
目录名是根据文件名、文件大小以及上次编译的日期和时间创建的。此方案基于以下假设:如果重新编译非托管 COM+ 组件,则需要生成新的代理。而这又是基于以下假设:如果要对代码做出更改,只能在运营环境中重新编译代码。
由于存在 SoapCache 目录,所以如果在同一计算机的不同虚拟根发布了相同的非托管组件,而不是生成代理程序集,则位于缓存中的非托管组件将被重新使用。这是为了确保组件的加强名称签名(以及由此生成的标识)可以通过虚拟根共享。
如果将 SOAP 启用的非托管 COM+ 组件作为服务器应用程序导出,然后导入到其他服务器,缓存的代理元数据将被一起带走,因此不同的服务器可以共享相同的非托管程序集的同一托管标识。此外,如果用户要生成或编写并签名自己的代理,只需将元数据放入相应的缓存目录中,当服务器上发生 SOAP 发布时就会使用此元数据。这里应用的基本规则是,为避免不必要地扩散用于同一非托管组件的已签名的代理,如果缓存中存在可替代的文件则不生成程序集。
客户端配置
客户端的配置工作也是必需的,最简单的情况(至少从用户的工作量来说)就是本文给出的第一个程序示例:
set SoapObj =
GetObject("soap:wsdl=http://www.xmethods.net/sd
/TemperatureService.wsdl")
WScript.Echo "Fairbanks 气温 = " & SoapObj.getTemp("99707")
当处理 WSDL 名字对象时,将会引发以下步骤:
进行检查,查看是否存在以前为此 URL 生成的代理。如果存在,则再次使用。(跳到步骤 4。)
如果不存在,则从 URL 检索 WSDL 并生成 C# 代理程序。这实质上与 soapsuds.exe 命令行实用程序(.NET 框架 SDK 所附带的)使用的逻辑相同。
C# 程序被编译为 DLL 并以与 URL 相匹配的名称命名(非法字符转换为文件名中可接受的字符)。
然后,生成的代理用于通过 .NET Remoting (WKO) 与 WSDL 中指定的远程服务器通信。
这些代理生成并保存在以下文件夹中:
C:\windows\system32\com\SoapAssembly
在客户端激活的情况中,客户端代理导入客户端计算机上所必需的已导出的 COM+ 应用程序。此应用程序的导出/导入将从服务器带来客户端激活所必需的已签名的元数据程序集。导入过程还生成配置文件,并放入 SoapAssembly 目录中。通常客户端配置文件采用以下格式:
<configuration>
<system.runtime.remoting>
<application>
<client url="http://MyServer/VB6Soap">
<activated type="VB6SoapSoapLib.CalcClass, VB6SoapSoapLib"/>
</client>
</application>
</system.runtime.remoting>
</configuration>
COM+ Web 服务在激活组件前读取此配置文件,这样便可以通过修改或替换此配置文件,在客户端计算机上潜在更改激活模型。
一切才刚刚开始
COM+ Web 服务的设计目的是简化结合 .NET Remoting 和 COM+ 服务(Windows XP 和 Windows .NET Server 系列均包含此服务)的过程。它只是为了简化常见的任务,并非包含所有的选项或涵盖用户可能遇到的各种情况。与使用向导在 Visual Studio .NET 中创建程序类似,某些高级的任务留给用户自行解决。为了使用户可以扩展,生成的项目很少被完全删除。此外,XML 类用于编辑生成的配置文件,如果已经存在配置文件,则会在该文件中添加或删除节点,以反映来自组件服务管理工具或 Microsoft COM+ 管理 SDK 的更改。COM+ Web 服务的设计使用户可以轻松地扩展或自定义已经生成的内容。
总之,COM+ Web 服务为现有的 Visual Basic 和 Visual C++ COM+ 组件,以及在 Visual Basic .NET 和 C# 中编写的新托管的 ServicedComponents,提供了一条实现 XML Web Services 和 SOAP 的简单途径。