日期:2012-09-05  浏览次数:20421 次

SOAP 与 DCOM 的局限性和区别


.NET Remoting 的目的之一是提供丰富的分布式环境,使开发人员能够在此环境中对序列化协议(格式化程序)和网络协议(频道)进行组合与匹配。.NET 框架 1.0 版本中的 COM+ Web 服务仅支持一种格式化程序 (SOAP) 和一种频道 (HTTP)。这并不是说其他频道和格式化程序不能使用 ServicedComponents 或 COM+,而是说没有自动配置为这些备用频道和格式化程序提供客户端和服务器端点。
目前已经有用各种语言编写的大量 COM+ 组件。如果可以使用 COM+ Web 服务将所有这些组件启用为 Web 服务,那就太好了。但正如使用 .NET 框架 1.0 版本一样,并非所有现有的 COM 组件都可以使用 COM+ Web 服务。虽然多数具备类型库的现有组件可以正常工作,但是此版本不支持某些组件,例如 Windows 脚本组件 (WSC) 组件。某些复杂的类型库(其接口具有多重继承级别,或依赖于多个类型库)可能无法正常工作。此外,由于类型库转换的局限性,只有类型库中默认的接口才可以作为 Web 服务。
COM+ Web 服务并不是适用于所有现有非托管 COM+ 组件的完整解决方案。现有非托管 COM+ 组件中有一大部分是使用多种编程语言编写而成的,由于不可能测试所有可能的类型库(由支持 COM+ 的各种编译器生成),因此某些非托管 COM+ 组件不能使用 COM+ Web 服务正确发布。COM+ Web 服务的目的之一就是最大程度减少做出这种评估所需的时间和精力。只需将非托管 COM+ 组件发布为 COM+ Web 服务,开发人员就可以迅速判断是否可以将其用作 Web 服务。如果遇到问题,则可以通过若干替代方法来处理现有的非托管组件。这些替代方法包括编写托管或非托管的包装程序,这些包装程序提供的兼容接口可以发布为 Web 服务。多数情况下,编写这样的包装程序的工作量比重新编写整个组件要少得多。这就尽可能减少了将现有的应用程序应用为 XML Web Services 所需的开发和测试工作。
使用非托管(Visual Basic 6.0 或 Visual C++)服务器时,通常越早绑定托管客户端应用程序和 SOAP,越能更好地工作。在某些情况下,如果将生成的元数据用作后期绑定的跨计算机远程代理程序,它可能无法正常工作。
在通过 HTTP 使用 SOAP 格式化程序的情况下,仍然可以使用许多选项(取决于目标部署环境)。COM+ Web 服务为服务器和 CAO 客户端配置生成基于 XML 的远程配置文件。(WKO 激活的 URL 引用已嵌入生成的客户端代理,因此不需要配置文件。)COM+ Web 服务生成直观的功能性配置文件,可由用户自定义以满足任何通过 HTTP 的直接 SOAP 通信所不能满足的需求。可进行自定义的区域包括用户身份验证,如下例所示:
<?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>  </application> </system.runtime.remoting> <identity impersonate="true" /></configuration>

上例中添加的突出显示的行可以在激活 COM+ 组件(通过 SOAP 调用)时使用用户的身份标识。(默认情况下,IIS 虚拟根使用标准的 IIS 身份验证。)这样在使用 SOAP 时可以实现 COM+ 的分区(一种 COM+ Windows .NET Server 功能),从而可根据用户的身份标识来实际调用不同的组件。
另一个可以自定义的区域包括客户端激活对象的生存期管理,如下例所示:
<?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 激活将从缓冲池中检