監(jiān)理公司管理系統(tǒng) | 工程企業(yè)管理系統(tǒng) | OA系統(tǒng) | ERP系統(tǒng) | 造價咨詢管理系統(tǒng) | 工程設(shè)計管理系統(tǒng) | 甲方項目管理系統(tǒng) | 簽約案例 | 客戶案例 | 在線試用
X 關(guān)閉
重慶OA行業(yè)資訊

當(dāng)前位置:工程項目OA系統(tǒng) > 泛普各地 > 重慶OA系統(tǒng) > 重慶OA行業(yè)資訊

COM+ Web服務(wù):通過復(fù)選框路由到XML Web Services

申請免費(fèi)試用、咨詢電話:400-8352-114

AMTeam.org

COM+ Web服務(wù):通過復(fù)選框路由到 XML Web Services


John Noss 和 Jonathan Hawkins

Microsoft Corporation

2001年11月

摘要:COM+ Web 服務(wù)新增了某些功能,可與 Microsoft .NET Remoting 集成,并通過 SOAP for COM+ 組件實(shí)現(xiàn) XML Web Services 發(fā)布的復(fù)選框激活。本文通過幾個示例介紹基本的互操作性、配置以及托管和非托管 COM+ 組件(在 Microsoft Windows .NET Server 和 Microsoft Windows XP Professional 上作為 XML Web Services 發(fā)布)的部署。

簡介

COM+ Web 服務(wù)新增了某些功能,可與 Microsoft .NET Remoting 集成,并通過 SOAP for COM+ 組件實(shí)現(xiàn) XML Web Services 發(fā)布的復(fù)選框激活。本文通過幾個示例介紹基本的互操作性、配置以及托管和非托管 COM+ 組件(在 Microsoft Windows .NET Server 和 Microsoft? Windows? XP Professional 上作為 XML Web Services 發(fā)布)的部署。還通過示例介紹了幾個新功能,使運(yùn)行 Windows XP 的客戶端能夠訪問遠(yuǎn)程服務(wù)器上的 XML Web Services。

當(dāng)開發(fā)人員使用 .NET Remoting 和托管代碼來完善現(xiàn)有的非托管 COM+ 服務(wù)器和客戶端代碼時,這些功能可以幫助他們利用和簡化遷移過程。在 .NET 框架的測試階段,有許多用戶問及如何配置 .NET Remoting 來進(jìn)行簡單的跨計算機(jī)激活操作。COM+ Web 服務(wù)的解決方案是同時自動配置服務(wù)器 (Microsoft Windows .NET Server) 和客戶端 (Microsoft Windows XP Professional) 計算機(jī),使用 .NET Remoting 來提供 SOAP 以替代 DCOM。

Microsoft Windows XP 和 Microsoft .NET 框架是本年度發(fā)布的兩個最重要的軟件。二者的目的都是為了簡化過程并提高軟件開發(fā)人員的能力,因此利用這兩種產(chǎn)品并發(fā)揮各自優(yōu)勢來提供一套集成的、易于使用的解決方案就成為自然之選。COM+ Web 服務(wù)提供了一種簡單的方法,可以將 COM+ 組件發(fā)布為 XML Web Services ;還提供了新的集成功能,用于從客戶端計算機(jī)訪問 XML Web Services。從以下 Microsoft Visual Basic Scripting Edition (VBScript) 示例中可以了解其易于使用的特點(diǎn),該示例用于確定 Alaska 的 Fairbanks 的當(dāng)前氣溫。請在 Windows XP(已安裝 .NET 框架)或 Windows .NET Server 上運(yùn)行此示例:

set SoapObj = GetObject

   ("soap:wsdl=http://www.xmethods.net/sd/TemperatureService.wsdl")

WScript.Echo "Fairbanks 氣溫 = " & SoapObj.getTemp("99707")

在上面的示例中,服務(wù)器是在 Linux 上運(yùn)行的 Apache SOAP Server,但也可以使用任何具有標(biāo)準(zhǔn) Web 服務(wù)說明語言 (WSDL) 描述功能的 SOAP V1.1 服務(wù)器。

注意: 如果出現(xiàn)“未找到服務(wù)器”錯誤,您需要在控制面板的 Internet 選項中手動配置防火墻設(shè)置。

使用 SOAP 作為計算機(jī)之間通信協(xié)議的優(yōu)點(diǎn)之一,在于它增加了可以交互操作的計算機(jī)的種類。.NET Remoting 具有以下兩種基本操作模型:

已知對象 (WKO): WKO 是 SOAP V1.1 所支持的最常見的 XML Web Services 模型。它允許與其他運(yùn)行 SOAP V1.1 兼容堆棧的計算機(jī)協(xié)同工作。服務(wù)器和客戶端可以是運(yùn)行 Apache SOAP 的非 Windows 服務(wù)器和運(yùn)行 pocketSOAP 的 Pocket PC,也可以是基于 Windows 的服務(wù)器和客戶端。唯一的要求是服務(wù)器上必須安裝了與 WSDL 1.1 版本兼容的描述功能,以便生成相應(yīng)的代理。此代理是在運(yùn)行時生成的,并且第一次使用 WSDL 名字對象時沒有用戶介入。

客戶端激活的對象 (CAO): CAO 提供了更豐富的開發(fā)環(huán)境,包括穩(wěn)定持久的連接。較之典型的 XML Web Services 模型,它更類似于 DCOM 模型,但要求在服務(wù)器和客戶端上都安裝有某一版本的 .NET 框架。

COM+ Web 服務(wù)可以使用 WKO 和 CAO 兩種激活模型,而且所有的服務(wù)器應(yīng)用程序都可以提供 WKO 和 CAO 端點(diǎn)。通過組合使用激活模型、XML Web Services 和 .NET Remoting,開發(fā)人員可以輕松地組合和匹配托管及非托管的客戶端和服務(wù)器。下表所示為兩種激活模型所支持方案的示例。

表 1:WKO 模型支持的方案

WKO 客戶端 WKO 服務(wù)器 VB 6.0 或非托管 C++ VB 6.0 或非托管 C++ VB 6.0 或非托管 C++ VB .NET 或 C# VB 6.0 或非托管 C++ SOAP V1.1(在 WSDL 中描述) VB 6.0 或非托管 C++ Microsoft SOAP(ATL Server,SOAP TK) C# 或 VB .NET SOAP V1.1(在 WSDL 中描述) C# 或 VB .NET VB 6.0 或非托管 C++ C# 或 VB .NET VB .NET 或 C# C# 或 VB .NET Microsoft SOAP(ATL Server,SOAP TK) Microsoft SOAP Toolkit V2.0 VB 6.0 或非托管 C++ Microsoft SOAP Toolkit V2.0 C# 或 VB .NET SOAP v1.1 VB 6.0 或非托管 C++ SOAP v1.1 C# 或 VB .NET

表 2:CAO 模型支持的方案

CAO 客戶端 CAO 服務(wù)器 C# 或 VB .NET(早期綁定) VB 6.0 或非托管 C++ VB 6.0 或非托管 C++ VB 6.0 或非托管 C++ VB 6.0 或非托管 C++ C# 或 VB .NET C# 或 VB .NET C# 或 VB .NET


 這種新的 COM+ Web 服務(wù)適用于以下用戶:

當(dāng)前安裝有 Microsoft? Visual Basic? 6.0 或者非托管 Microsoft Visual C++? COM+ 應(yīng)用程序(需要通過防火墻才能進(jìn)行某些激活操作)的 COM+ 用戶。(使用 SOAP 并不排斥通過 DCOM 訪問服務(wù)器上的相同組件,客戶端計算機(jī)可以選擇協(xié)議。)對于這些客戶來說,如果要使用 SOAP 而不是 DCOM,則使用客戶端代理導(dǎo)出和 CAO 模型都不需要更改客戶端和服務(wù)器應(yīng)用程序。只需要在服務(wù)器應(yīng)用程序上啟用 SOAP,將其作為客戶端代理導(dǎo)出,然后將代理安裝在要用作 SOAP 客戶端的 Windows XP 計算機(jī)上。

完全遷移到 Windows XP 和 Windows .NET Server 上的托管代碼的公司。COM+ Web 服務(wù)有助于在連接的兩端設(shè)置遠(yuǎn)程端點(diǎn)。

需要在上述兩種方案中組合和匹配各種服務(wù)的開發(fā)人員,以及編寫托管服務(wù)器組件、或帶有非托管服務(wù)器組件的托管客戶端應(yīng)用程序的開發(fā)人員。在第二種情況中,開發(fā)人員可以利用 COM+ Web 服務(wù),在用托管代碼替換之前充分利用早期的非托管組件。

簡單的已知對象 (WKO) 示例

除了對 Linux 和 ApacheIn 提供 SOAP 支持外,將 COM+ Web 服務(wù)應(yīng)用于其他 Microsoft 產(chǎn)品(例如 ATL Server Web 服務(wù))也非常簡單。只需使用 Microsoft Visual Studio? .NET 在服務(wù)器上生成、編譯和部署默認(rèn)的 ATL Web 服務(wù)即可。對它進(jìn)行訪問的客戶端代碼如下(請用駐留 ATL Server 應(yīng)用程序的 Web 服務(wù)器名稱替換 MyServer,用您的 ATL Server DLL 的名稱替換 JALTServer):

mon="soap:wsdl=http://MyServer/JALTServer/JALTServer.dll?
   Handler=GenJALTServerWSDL"
set c = GetObject(mon)
WScript.Echo c.HelloWorld("COM+ Web 服務(wù)")

上述示例簡單說明了 Microsoft Windows XP 和 Microsoft Windows .NET 服務(wù)器所包含的一個新的 SOAP 名字對象。

數(shù)據(jù)發(fā)布

如果您只想提供數(shù)據(jù)而不是使用數(shù)據(jù),那么只需選擇一個復(fù)選框,然后輸入 IIS 虛擬根名稱的值。要創(chuàng)建完整的 COM+ Web 服務(wù),請執(zhí)行以下步驟:

使用 Visual Basic 6.0 創(chuàng)建簡單的 Microsoft ActiveX? DLL,并輸入以下代碼:

Function Add(ByVal Value1 As Double, ByVal Value2 As Double) As Double
 Add = Value1 + Value2
End Function

在 Visual Basic 項目屬性頁上的 General選項卡中,設(shè)置 Unattended Execution 和 Retained in Memory,并在 Component 選項卡中選擇 Remote Server Files。使用 Visual Basic 開發(fā)環(huán)境生成此 DLL。

在創(chuàng)建 Visual Basic 應(yīng)用程序之后,需要將其注冊為 COM+ 應(yīng)用程序。啟動組件服務(wù)管理工具,在 Windows XP 上創(chuàng)建 COM+ 應(yīng)用程序。(在此示例中,應(yīng)用程序被命名為 VB6Soap。)將所創(chuàng)建的 DLL 作為組件導(dǎo)入,然后瀏覽到 COM+ 應(yīng)用程序?qū)傩皂摰? Activation 選項卡,選擇 Uses SOAP,輸入一個 SOAP Vroot(例如,VB6Soap),然后單擊 OK(如圖 1 所示)。

圖 1:VB6Soap COM+ 應(yīng)用程序?qū)傩皂?/FONT>

現(xiàn)在,應(yīng)用程序已發(fā)布為 XML Web Services,并且可以使用 SOAP 激活。使用 Internet Explorer 瀏覽到 http://localhost/VB6Soap/default.aspx,您會在該 aspx 頁上發(fā)現(xiàn)一個超鏈接,通過它可以鏈接到您的組件所生成的 WSDL。以下 VBScript 將激活您的組件:

set c = GetObject
   ("soap:wsdl=http://localhost/VB6Soap/VB6Soap.Calc.soap?WSDL")
for i = 1 to 10
 WScript.Echo i & " " & c.Add(i,i) & " " & Time
next

如果用您的服務(wù)器名稱替換上面腳本中的 localhost,它也可以在遠(yuǎn)程客戶端計算機(jī)上正常工作。引用的頁面(在此示例中為 VB6Soap.Calc.soap)是以 .soap 后綴結(jié)尾的組件 ProgID。

要通過 SOAP Toolkit(與 Windows XP Professional 一起提供,并且不使用 .NET Remoting)訪問同一端點(diǎn),請運(yùn)行以下 VBScript:

set c = CreateObject("MSSOAP.SOAPClient")
c.mssoapinit("
http://localhost/VB6Soap/VB6Soap.Calc.soap?WSDL")
for i = 1 to 10
 WScript.Echo i & " " & c.Add(i,i) & " " & Time
next

要簡化在服務(wù)器上發(fā)布 SOAP 的過程,您可以使用 Microsoft C#? 或 Visual Basic .NET,并從 ServicedComponent 繼承。下面是簡單托管組件的托管代碼示例:

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.EnterpriseServices;

[assembly: ApplicationName("CSSoap")]
[assembly: ApplicationActivation(ActivationOption.Server,
   SoapVRoot="CSSoap")]
[assembly: AssemblyKeyFile("CSSoap.snk")]
namespace CSSoap
{
  public interface ICalc
  {
   double Add (double Value1, double Value2);
  }

  [ClassInterface(ClassInterfaceType.AutoDual)]
  [TransactionAttribute(TransactionOption.None)]
  public class Calc : ServicedComponent, ICalc
  {
   public double Add (double Value1, double Value2);
   {
      return (Value1 + Value2);
   }
  }
}

上述示例中值得注意的是 ApplicationActivation 屬性:

[assembly: ApplicationActivation(ActivationOption.Server,
   SoapVRoot="CSSoap")]

建立 C# 組件,將它安裝在全局程序集緩存中,然后運(yùn)行 regsvcs.exe 將它注冊為 COM+ 應(yīng)用程序。這樣,該組件就被發(fā)布為 IIS 虛擬根和 SOAP 端點(diǎn)。要成功地遠(yuǎn)程使用 ServicedComponent,還需要使用 gacutil.exe 或 .NET 框架用戶界面,將這個編譯后的程序集放入全局程序集緩存 (GAC) 中。要通過 WSDL 訪問此 SOAP 端點(diǎn),請使用以下 VBScript:

set c = GetObject
   ("soap:wsdl=http://localhost/CSSoap/CSSoap.Calc.soap?WSDL")
for i = 1 to 10
 WScript.Echo i & " " & c.Add(i,i) & " " & Time
next

作為 SOAP 交互操作性的簡單示例,SOAP Toolkit 與 Windows XP Professional 一起提供,并且即使運(yùn)行 Windows XP 的客戶端計算機(jī)上沒有安裝 .NET 框架,使用以下 VBScript 也可以訪問 COM+ SOAP 端點(diǎn):

set c = CreateObject("MSSOAP.SOAPClient")
c.mssoapinit("
http://localhost/CSSoap/CSSoap.Calc.soap?WSDL?
for i = 1 to 10
 WScript.Echo i & " " & c.Add(i,i) & " " & Time
next

為簡單起見,上述示例全部使用 VBScript 來訪問 Web 服務(wù)。其實(shí)也可以通過 SOAP WSDL 名字對象使用 Visual C+、Visual Basic 6.0、Visual Basic .NET 或 C# 進(jìn)行編寫。例如,Visual Basic .NET 也可以使用編譯的托管代碼訪問同一對象,如下例所示:

Imports System
Imports System.Runtime.InteropServices
Module WKOClient
 Sub Main()
    Dim WSDLMoniker =
      "soap:wsdl=http://localhost/CSSoap/CSSoap.Calc.soap?WSDL"
      Dim obj as Object
   obj = Marshal.BindToMoniker(WSDLMoniker)
   Console.WriteLine(obj.Add(1,2))
 End Sub
End Module

使用 VBScript 是為了表明,托管的和非托管的客戶端都可以訪問發(fā)布為 COM+ Web 服務(wù)的 COM+ 組件。在大型組織或應(yīng)用程序中,很難一次轉(zhuǎn)換所有部分,COM+ Web 服務(wù)允許將一部分應(yīng)用程序轉(zhuǎn)換為托管代碼,而無需立即全面重新編寫現(xiàn)有的應(yīng)用程序。

簡單的客戶端激活對象 (CAO) 示例

服務(wù)器上的 COM+ Web 服務(wù)發(fā)布將每一組件發(fā)布為 WKO 和 CAO 兩種形式,因此不需要額外的服務(wù)器配置。在服務(wù)器上唯一要做的操作是,在選擇 Uses SOAP 復(fù)選框(位于 COM+ 應(yīng)用程序?qū)傩皂摰?Activation 選項卡上)并在 SOAP VRoot 文本框中輸入值以后,將 COM+ 應(yīng)用程序作為代理程序?qū)С?。下面顯示了導(dǎo)出代理應(yīng)用程序的必要步驟:

用鼠標(biāo)右鍵單擊組件服務(wù)管理工具中的 VB6Soap COM+ 應(yīng)用程序,并選擇 Export,如圖 2 所示。


 

圖 2:組件服務(wù)管理工具

在圖 3 所示的 COM+ 應(yīng)用程序?qū)С鱿驅(qū)е?,輸入代?.msi 文件的位置和名稱。
 

圖 3:COM+ 應(yīng)用程序?qū)С鱿驅(qū)?

將代理 .msi 文件安裝在單獨(dú)的客戶端計算機(jī)上,作為預(yù)先生成的 COM+ 應(yīng)用程序。

安裝時將對代理進(jìn)行適當(dāng)?shù)呐渲?,以便通過 SOAP 訪問正確的服務(wù)器和虛擬根。對于客戶端激活,可以不使用 WSDL 名字對象,而使用常規(guī)非托管的 COM+ 激活(例如,CoCreateInstance、CreateObject 等)。在服務(wù)器上創(chuàng)建并在單獨(dú)的客戶端計算機(jī)上安裝上述 Visual Basic 計算器示例的應(yīng)用程序代理后,以下 VBScript 將通過 SOAP 訪問該服務(wù)器:

set c = CreateObject("VB6Soap.Calc")
for i = 1 to 10
 WScript.Echo i & " " & c.Add(i,i) & " " & Time
next

如果代理程序沒有啟用 COM+ Web 服務(wù),則上述 VBScript 代碼將使用 DCOM 訪問服務(wù)器應(yīng)用程序。

事務(wù)性組件示例

簡單的計算器遠(yuǎn)算不上工作量繁重的業(yè)務(wù)應(yīng)用程序,因此我們現(xiàn)在考慮帶有對象池的適于 COM+ 事務(wù)性組件的應(yīng)用程序。

最容易管理和配置的組件是由 ServicedComponent 導(dǎo)出的托管代碼組件,如以下 C# 示例所示:

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.EnterpriseServices;
using System.Data;
using System.Data.SqlClient;

[assembly: ApplicationName("SCTrans")]
[assembly: ApplicationActivation(ActivationOption.Server,
   SoapVRoot="SCTrans")]
[assembly: AssemblyKeyFile("SCTrans.snk")]
namespace SCTrans
{
  public interface ISCTrans
  {
   string CountUp (string Key);
  }

  [ObjectPooling(MinPoolSize=0, MaxPoolSize=25)]
  [JustInTimeActivation(true)]
  [ClassInterface(ClassInterfaceType.AutoDual)]
  [TransactionAttribute(TransactionOption.RequiresNew)]
  public class SCTransSQLNC : ServicedComponent, ISCTrans
  {
   [AutoComplete]
   public string CountUp (string Key)
   {
      _command = new SqlCommand("", _connection);
      _command.CommandType = CommandType.Text;
      _command.Connection.Open();
     _command.CommandText = "UPDATE CallCount WITH (ROWLOCK) SET
      CallCount = CallCount + 1 WHERE Machine='" + Key + "'";
     _command.ExecuteNonQuery();
      _command.Connection.Close();
     _numcalls++;
     return (_numcalls + " NC " + _guid);
   }

   protected override bool CanBePooled()
   {
     return true;
   }
   private int _numcalls = 0;
   private string _guid = Guid.NewGuid().ToString();
   private SqlConnection _connection =
   new SqlConnection("user id=MyUser;password=My!Password;
   database=SoapTest;server=MyServer");
   private SqlCommand _command;
  
  }
}

要建立并運(yùn)行此 C# 組件,在完成編輯連接值以連接到 Microsoft SQL Server? 數(shù)據(jù)庫之后,需要使用 sn.exe 生成 sctrans.snk 加強(qiáng)名稱關(guān)鍵字文件,然后在 using 語句中使用程序集引用對其進(jìn)行編譯。如果您在服務(wù)器上進(jìn)行部署,應(yīng)使用 gacutil.exe(如果正在使用 SDK)或通過 .NET 框架用戶界面將程序集放入 GAC,然后運(yùn)行 regsvcs.exe,注冊 COM+ 托管組件。Regsvcs.exe 將使用以下屬性,將組件發(fā)布為服務(wù)器上的 SOAP 端點(diǎn)和服務(wù)器(進(jìn)程外)激活:

[assembly: ApplicationActivation(ActivationOption.Server,
   SoapVRoot="CSSoapSQL")]

此組件在每種方法調(diào)用中使用不同的事務(wù),具有一個自動完成方法,并被配置為進(jìn)行緩沖。使用托管和非托管 COM+ 組件時,對象池和事務(wù)將如所預(yù)期的那樣通過 SOAP 運(yùn)行。例如,如果使用下列 VBScript 通過 SOAP 訪問以下 ServicedComponent:

mon = "soap:wsdl=http://jnoss3/sctrans/SCTrans.SCTransSQLNC.soap?WSDL"
WScript.Echo(mon)
for i = 1 to 2
 set c = GetObject(mon)
 for j = 1 to 10
  WScript.Echo i & " " & j & " " & c.CountUp("SCWKONC")
 next
next

將顯示以下輸出內(nèi)容:

C:moniker>actscwko
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

soap:wsdl=http://jnoss3/sctrans/SCTrans.SCTransSQLNC.soap?WSDL
1 1 486 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672
1 2 487 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672
1 3 488 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672
1 4 489 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672
1 5 490 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672
1 6  8 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce
1 7  9 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce
1 8 10 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce
1 9 494 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672
1 10 495 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672
2 1 13 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce
2 2 14 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce
2 3 15 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce
2 4 499 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672
2 5 17 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce
2 6 501 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672
2 7 502 NC 6e41f32f-74be-45f0-94c0-989e7e1c5672
2 8 19 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce
2 9 20 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce
2 10 21 NC af26b53b-4a1f-48c8-8880-518c2b55a7ce

這就是所預(yù)期的緩沖的組件:從緩沖池中拖出對象并重新使用。使用客戶端激活的緩沖組件的行為都是相同的。

非托管組件的對象池和事務(wù)也如所預(yù)期的那樣運(yùn)行(雖然 Visual Basic 6.0 組件不支持對象池)。需要為大多數(shù)非托管應(yīng)用程序通過 COM+ 管理工具設(shè)置緩沖和事務(wù)屬性。

傳遞引用

WKO 與 CAO 模型的一個關(guān)鍵區(qū)別在于它們向有狀態(tài)的對象傳遞引用的能力。以下是 C# ServicedComponent 示例,顯示了此操作的基本步驟:

using System;
using System.Reflection;
using System.EnterpriseServices;
using System.Runtime.InteropServices;

[assembly: ApplicationName("RefPass")]
[assembly: ApplicationActivation(ActivationOption.Server,
   SoapVRoot="RefPass")]
[assembly: AssemblyKeyFile("RefPass.snk")]
namespace RefPass
{
  public interface IParent
  {
    string SetRef(object inKid);
    object GetRef();
    string CountUp(object obj);
  }

  public interface IChild
  {
    string GetValue ();
    string CountUp();
    void SetName(string key);
  }

  [ClassInterface(ClassInterfaceType.AutoDual)]
  public class Parent: ServicedComponent, IParent
  {
    protected Child _kid = null;

    public string SetRef(object inKid)
    {
      _kid = (Child)inKid;
      return _kid.GetValue();
    }

    public object GetRef()
    {
      return (object)_kid;
    }

    public string CountUp(object obj)
    {
      Child kid = (Child)obj;
      if (kid == null) return _kid.CountUp();
      else return kid.CountUp();
    }
 }

  [ClassInterface(ClassInterfaceType.AutoDual)]
  public class Child : ServicedComponent, IChild
  {
    private int _counter = 0;
    private string _name = "none";
    public string CountUp() { _counter++; return GetValue(); }
    public string GetValue() { return (_name + " "
   +_counter.ToString()); }
    public void SetName(string key) { _name = key; }
  }
}

此 C# 程序有兩個類:Child 和 Parent。如果運(yùn)行以下 VBScript 示例,WKO 與 CAO 模型的區(qū)別會更加明顯:

set c1 = GetObject
   ("soap:wsdl=http://jnoss4/refpass/RefPass.Child.soap?wsdl")
set c2 = GetObject
   ("soap:wsdl=http://jnoss4/refpass/RefPass.Child.soap?wsdl")
c1.SetName("C1")
WScript.Echo c1.CountUp()
WScript.Echo c1.CountUp()
WScript.Echo c1.CountUp()
WScript.Echo c1.CountUp()
WScript.Echo c1.CountUp()
C2.SetName("C2")
WScript.Echo c2.CountUp()
WScript.Echo c2.CountUp()
WScript.Echo c2.CountUp()
WScript.Echo c2.CountUp()
WScript.Echo c2.CountUp()

運(yùn)行時將顯示以下輸出內(nèi)容:

C:moniker>refpasswko
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

none 1
none 1
none 1
none 1
none 1
none 1
none 1
none 1
none 1
none 1

名稱和值說明了單一調(diào)用已知對象的無狀態(tài)性質(zhì),因為組件是使用不同的方法調(diào)用創(chuàng)建的,所以方法調(diào)用之間不保留名稱或值。

如果導(dǎo)出客戶端代理,然后導(dǎo)入到另一臺客戶端計算機(jī)上,并且運(yùn)行了下面的 VBScript,則 SOAP 激活將是 CAO 而不是 WKO:

'直接創(chuàng)建兩個對象
set c1=CreateObject("RefPass.Child")
set c2=CreateObject("RefPass.Child")
'設(shè)置第一個對象的名稱,并調(diào)用數(shù)次
'以遞增對象內(nèi)部計數(shù)器
c1.SetName("C1")
WScript.Echo c1.CountUp()
WScript.Echo c1.CountUp()
WScript.Echo c1.Countup()
WScript.Echo c1.CountUp()
WScript.Echo c1.Countup()
'設(shè)置第一個對象的名稱,并調(diào)用數(shù)次
'以遞增對象內(nèi)部計數(shù)器
c2.SetName("C2")
WScript.Echo c2.CountUp()
WScript.Echo c2.CountUp()
WScript.Echo c2.Countup()
WScript.Echo c2.CountUp()
WScript.Echo c2.Countup()
'創(chuàng)建父對象
set p=CreateObject("RefPass.Parent")
'將子對象傳遞到父對象,并從父對象調(diào)用子對象
WScript.Echo p.SetRef(c1)
WScript.Echo p.CountUp(c2)
WScript.Echo p.CountUp(c2)
WScript.Echo p.CountUp(c2)
WScript.Echo p.CountUp(c2)
'現(xiàn)在調(diào)用存儲在父對象內(nèi)部的子對象
dim c9
WScript.Echo p.CountUp(c9)
'從父對象獲取該對象并直接調(diào)用
Set c3 = p.GetRef()
WScript.Echo c3.CountUp()

從命令行運(yùn)行時,將顯示以下輸出內(nèi)容:

C:moniker>refpasscl
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

C1 1
C1 2
C1 3
C1 4
C1 5
C2 1
C2 2
C2 3
C2 4
C2 5
C1 5
C2 6
C2 7
C2 8
C2 9
C1 6
C1 7

即使在通過 SOAP 調(diào)用時,CAO 激活也會保留狀態(tài),并且允許通過 SOAP 來回傳遞對象引用。名稱和值都保留在服務(wù)器上的類實(shí)例中,并且引用可以正確工作。這兩種腳本都調(diào)用相同的編譯 C# 組件,只是 .NET Remoting 激活模型不同。

除了使用 CreateObject 調(diào)用 CAO 激活外,還可以使用帶有 COM+ 的名字對象,它可以提供 CAO 激活來替代 WKO(類型名稱和程序集名字對象)。以下腳本:

'直接創(chuàng)建兩個對象
set c1=GetObject("soap:typename=RefPass.Child,assembly=RefPass")
set c2=GetObject("soap:typename=RefPass.Child,assembly=RefPass")
'設(shè)置第一個對象的名稱,并調(diào)用數(shù)次
'以遞增對象內(nèi)部計數(shù)器
c1.SetName("C1")
WScript.Echo c1.CountUp()
WScript.Echo c1.CountUp()
WScript.Echo c1.Countup()
WScript.Echo c1.CountUp()
WScript.Echo c1.Countup()
'設(shè)置第二個對象的名稱,并調(diào)用數(shù)次
'以遞增對象內(nèi)部計數(shù)器
c2.SetName("C2")
WScript.Echo c2.CountUp()
WScript.Echo c2.CountUp()
WScript.Echo c2.Countup()
WScript.Echo c2.CountUp()
WScript.Echo c2.Countup()
'創(chuàng)建父對象
set p=GetObject("soap:typename=RefPass.Parent,assembly=RefPass")
'將子對象傳遞到父對象,并從父對象調(diào)用子對象
WScript.Echo p.SetRef(c1)
WScript.Echo p.CountUp(c2)
WScript.Echo p.CountUp(c2)
WScript.Echo p.CountUp(c2)
WScript.Echo p.CountUp(c2)
'現(xiàn)在調(diào)用存儲在父對象內(nèi)部的子對象
dim c9
WScript.Echo p.CountUp(c9)
'從父對象獲取該對象并直接調(diào)用
Set c3 = p.GetRef()
WScript.Echo c3.CountUp()

將顯示以下輸出內(nèi)容:

C:moniker>refpassca
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

C1 1
C1 2
C1 3
C1 4
C1 5
C2 1
C2 2
C2 3
C2 4
C2 5
C1 5
C2 6
C2 7
C2 8
C2 9
C1 6
C1 7

這與上面的 VBScript CreateObject(ProgID) 示例的輸出內(nèi)容相同。因為常規(guī) COM+ 激活路徑被 SOAP 代理應(yīng)用程序截獲,所以可以使用 CoCreateInstance、CreateInstance 以及其他傳統(tǒng)的 COM+ 激活方法來調(diào)用使用 COM+ Web 服務(wù)的客戶端激活的對象。

程序集和類型名稱名字對象,對于從托管代碼客戶端遠(yuǎn)程獲取預(yù)先配置的客戶端激活也很有用,如下例所示:

Imports System
Imports System.Runtime.InteropServices
Module RefPassCl
Sub Main()
    Dim ChildMoniker = "soap:assembly=RefPass,typename=RefPass.Child"
    Dim ParentMoniker = "soap:assembly=RefPass,typename=RefPass.Parent"
    Dim c1,c2,p as Object
    c1 = Marshal.BindToMoniker(ChildMoniker)
    Console.WriteLine(c1.SetName("C1"))
    Console.WriteLine(c1.CountUp())
    Console.WriteLine(c1.CountUp())
    Console.WriteLine(c1.CountUp())
    Console.WriteLine(c1.CountUp())
    Console.WriteLine(c1.CountUp())
    c2 = Marshal.BindToMoniker(ChildMoniker)
    Console.WriteLine(c2.SetName("c2"))
    Console.WriteLine(c2.CountUp())
    Console.WriteLine(c2.CountUp())
    Console.WriteLine(c2.CountUp())
    Console.WriteLine(c2.CountUp())
    Console.WriteLine(c2.CountUp())
    p = Marshal.BindToMoniker(ParentMoniker)
    Console.WriteLine(p.SetRef(c1))
    Console.WriteLine(p.CountUp(c2))
    Console.WriteLine(p.CountUp(c2))
    Console.WriteLine(p.CountUp(c2))
    Console.WriteLine(p.CountUp(c2))
    Dim c9
    Console.WriteLine(p.CountUp(c9))
    Dim c3 = p.GetRef()
    Console.WriteLine(c3.CountUp())
 End Sub
End Module

編譯并運(yùn)行此 Visual Basic .NET 應(yīng)用程序,將產(chǎn)生與前面兩個 VBScript CAO 示例相同的輸出內(nèi)容。

因為服務(wù)器應(yīng)用程序?qū)⒔M件發(fā)布為 CAO 和 WKO 兩種形式,所以由遠(yuǎn)程客戶端選擇激活方法。雖然可能只對學(xué)術(shù)研究有意義,但是單一客戶端計算機(jī)確實(shí)可以使用同一組件的兩種遠(yuǎn)程激活方法,訪問遠(yuǎn)程服務(wù)器上同一個 SOAP 發(fā)布的虛擬根。

SOAP 與 DCOM 的局限性和區(qū)別

.NET Remoting 的目的之一是提供豐富的分布式環(huán)境,使開發(fā)人員能夠在此環(huán)境中對序列化協(xié)議(格式化程序)和網(wǎng)絡(luò)協(xié)議(頻道)進(jìn)行組合與匹配。.NET 框架 1.0 版本中的 COM+ Web 服務(wù)僅支持一種格式化程序 (SOAP) 和一種頻道 (HTTP)。這并不是說其他頻道和格式化程序不能使用 ServicedComponents 或 COM+,而是說沒有自動配置為這些備用頻道和格式化程序提供客戶端和服務(wù)器端點(diǎn)。

目前已經(jīng)有用各種語言編寫的大量 COM+ 組件。如果可以使用 COM+ Web 服務(wù)將所有這些組件啟用為 Web 服務(wù),那就太好了。但正如使用 .NET 框架 1.0 版本一樣,并非所有現(xiàn)有的 COM 組件都可以使用 COM+ Web 服務(wù)。雖然多數(shù)具備類型庫的現(xiàn)有組件可以正常工作,但是此版本不支持某些組件,例如 Windows 腳本組件 (WSC) 組件。某些復(fù)雜的類型庫(其接口具有多重繼承級別,或依賴于多個類型庫)可能無法正常工作。此外,由于類型庫轉(zhuǎn)換的局限性,只有類型庫中默認(rèn)的接口才可以作為 Web 服務(wù)。

COM+ Web 服務(wù)并不是適用于所有現(xiàn)有非托管 COM+ 組件的完整解決方案。現(xiàn)有非托管 COM+ 組件中有一大部分是使用多種編程語言編寫而成的,由于不可能測試所有可能的類型庫(由支持 COM+ 的各種編譯器生成),因此某些非托管 COM+ 組件不能使用 COM+ Web 服務(wù)正確發(fā)布。COM+ Web 服務(wù)的目的之一就是最大程度減少做出這種評估所需的時間和精力。只需將非托管 COM+ 組件發(fā)布為 COM+ Web 服務(wù),開發(fā)人員就可以迅速判斷是否可以將其用作 Web 服務(wù)。如果遇到問題,則可以通過若干替代方法來處理現(xiàn)有的非托管組件。這些替代方法包括編寫托管或非托管的包裝程序,這些包裝程序提供的兼容接口可以發(fā)布為 Web 服務(wù)。多數(shù)情況下,編寫這樣的包裝程序的工作量比重新編寫整個組件要少得多。這就盡可能減少了將現(xiàn)有的應(yīng)用程序應(yīng)用為 XML Web Services 所需的開發(fā)和測試工作。

使用非托管(Visual Basic 6.0 或 Visual C++)服務(wù)器時,通常越早綁定托管客戶端應(yīng)用程序和 SOAP,越能更好地工作。在某些情況下,如果將生成的元數(shù)據(jù)用作后期綁定的跨計算機(jī)遠(yuǎn)程代理程序,它可能無法正常工作。

在通過 HTTP 使用 SOAP 格式化程序的情況下,仍然可以使用許多選項(取決于目標(biāo)部署環(huán)境)。COM+ Web 服務(wù)為服務(wù)器和 CAO 客戶端配置生成基于 XML 的遠(yuǎn)程配置文件。(WKO 激活的 URL 引用已嵌入生成的客戶端代理,因此不需要配置文件。)COM+ Web 服務(wù)生成直觀的功能性配置文件,可由用戶自定義以滿足任何通過 HTTP 的直接 SOAP 通信所不能滿足的需求??蛇M(jìn)行自定義的區(qū)域包括用戶身份驗證,如下例所示:

<?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 調(diào)用)時使用用戶的身份標(biāo)識。(默認(rèn)情況下,IIS 虛擬根使用標(biāo)準(zhǔn)的 IIS 身份驗證。)這樣在使用 SOAP 時可以實(shí)現(xiàn) COM+ 的分區(qū)(一種 COM+ Windows .NET Server 功能),從而可根據(jù)用戶的身份標(biāo)識來實(shí)際調(diào)用不同的組件。

另一個可以自定義的區(qū)域包括客戶端激活對象的生存期管理,如下例所示:

<?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,則激活行為會更改為將所有傳入的方法調(diào)用都路由到一個組件,而不是原來的對于每個方法調(diào)用都激活一個新組件。

.NET Remoting(類似 .NET 框架的其余部分)支持垃圾回收,而不支持引用計數(shù)。這意味著在某些情況下,使用 COM+ Web 服務(wù)和 DCOM 時,非托管事務(wù) COM+ 組件的行為方式將有所不同。對于通過 WKO 單一調(diào)用發(fā)布的事務(wù)方法,調(diào)用 SetComplete 或選擇自動完成(通過選擇組件方法屬性頁的“返回此方法時自動停用該對象”復(fù)選框)是極其重要的,這是因為組件在進(jìn)行垃圾回收前不能被釋放。使用 DCOM 時,引用計數(shù)通常會導(dǎo)致在釋放組件時提交或放棄事務(wù),即使此法則被忽略。移動到 COM+ Web 服務(wù)環(huán)境時,在垃圾回收環(huán)境中,事務(wù)超時之前這是不能保證的。如果調(diào)用 SetComplete 失敗或?qū)⒎椒ㄅ渲脼樽詣油瓿墒。瑒t證明其自身的間歇無法提交事務(wù),因為組件被作為垃圾回收之前事務(wù)已超時。

設(shè)計時應(yīng)注意的事項

在 COM+ Web 服務(wù)中,如果選擇了 Uses SOAP 復(fù)選框(使用組件服務(wù)管理工具),將在 IIS 虛擬根上提供兩種不同的激活模型:WKO 和 CAO。哪一種模型更好?用戶應(yīng)該使用哪一種呢?

WKO 單一調(diào)用激活模型看起來似乎頗為費(fèi)事。每種方法調(diào)用都需要創(chuàng)建一個新組件,完成方法調(diào)用后,再將組件發(fā)送到內(nèi)存回收器。但是,如果特別注重性能并且只能使用 WKO 處理業(yè)務(wù)時,緩沖的 ServicedComponents 或緩沖的非托管 C++ 組件可以大大緩解單一調(diào)用激活的過程。使用緩沖的組件時,WKO 激活將從緩沖池中檢索對象,完成調(diào)用,然后將對象返回到緩沖池。此協(xié)議的無狀態(tài)性質(zhì)和緩沖池的使用提高了增加擴(kuò)展性的可能。在不緩沖對象的 WKO 單一調(diào)用中,對象的生命期僅限于調(diào)用過程。

另一方面,CAO 提供了服務(wù)器上單一激活的性能優(yōu)勢,還可以與某個組件的單一實(shí)例繼續(xù)進(jìn)行通信。通過從客戶端向服務(wù)器進(jìn)行多方法調(diào)用可以避免激活的缺點(diǎn)。如果服務(wù)器組件(ServicedComponent 或非托管 C++ 組件)被緩沖,則將從緩沖池中檢索對象,然后在完成方法調(diào)用時將對象返回到緩沖池。如果對象沒有被緩沖,則對象生命期取決于 web.config 文件中指定的租用生命期,或由組件自身編程設(shè)置。生命期是很重要的,因為直到生命期到期時垃圾回收器才會為組件釋放內(nèi)存。在高容量的 CAO 配置中,這會影響開發(fā)人員的某些設(shè)計決定。

更進(jìn)一步

如果您只是希望發(fā)布或使用應(yīng)用了 COM+ Web 服務(wù)的 Web 服務(wù),您可以到此為止。但是,如果您希望自定義、擴(kuò)展或簡單了解使用的流程,請繼續(xù)閱讀下面的內(nèi)容。下面的信息不是使用此項功能所必需的,但是如果您希望手動擴(kuò)展一些功能,這些信息可能會非常有用。COM+ Web 服務(wù)是一個簡單的包裝程序,通過由 .NET Remoting 提供的一套相當(dāng)豐富的服務(wù),開發(fā)人員或管理員可以輕松地對其進(jìn)行擴(kuò)展。

服務(wù)器 IIS 虛擬根

為使用此功能,并沒有在 .NET Remoting 中添加隱藏掛鉤,而是編寫了 COM+ 代碼以進(jìn)行必要配置,將 COM+ 端點(diǎn)發(fā)布為 IIS 虛擬根。在服務(wù)器上,這包括向服務(wù)器創(chuàng)建物理目錄作為虛擬根,以及生成 web.config 文件,以便通過 Remoting 來訪問組件。如果是非托管組件(Visual C++ 或 Visual Basic 6.0),也會生成代理元數(shù)據(jù),以便 Remoting 可以訪問組件。如果 Windows XP 系統(tǒng)目錄是 c:windows,則服務(wù)器配置文件和生成的所有元數(shù)據(jù)都將存儲在以下目錄樹中:

C:windowssystem32comSoapVRootsvrootname

當(dāng)在服務(wù)器上發(fā)布 SOAP 端點(diǎn)時,以下生成的文件將被放入此目錄中:

web.config: VRoot 的基本 Remoting 配置文件,包含許多選項,可供開發(fā)人員或系統(tǒng)管理員添加或編輯,以調(diào)整 Remoting 的性能和安全性。

default.disco: 如果您正在開發(fā)托管代碼客戶端,可與 Visual Studio .NET 一起使用此文件,來生成對已發(fā)布的 Web 服務(wù)的引用。如果您的業(yè)務(wù)伙伴希望在企業(yè)外聯(lián)網(wǎng)上開發(fā)自己的客戶端,這會特別有用。

default.aspx: 簡單的 Microsoft ASP.NET 頁,可以將每一組件發(fā)布為超鏈接。

上述所有文件都是默認(rèn)生成的。如果您希望刪除其中某些功能,只需編輯或刪除相應(yīng)的文件。(但是,如果刪除了 web.config 文件,來自 IIS 虛擬根的所有 SOAP 發(fā)布都會停止。)

所有生成的元數(shù)據(jù)都被放入以下目錄以及 GAC 中:

C:windowssystem32comSoapVRootsvrootnamebin

在 .NET Remoting 中,bin 目錄是一個很特殊的位置。當(dāng) HTTP 請求進(jìn)入 IIS 時,將在此目錄中搜索程序集,因此在許多情況下,bin 目錄中的發(fā)布是唯一必要的步驟。但是,在發(fā)布 SOAP 端點(diǎn)時,生成的程序集也被放入 GAC,這是因為虛擬根的程序集解決方案的范圍僅限于 bin 目錄和 GAC。如果您的代碼在同一臺計算機(jī)上從一個虛擬根向另一個傳遞引用,除非程序集在 GAC 中,否則目標(biāo)虛擬根中的引用解決方案將會失敗。如果您正在使用所生成的用于非托管 Visual Basic 6.0 或 Visual C++ 組件的元數(shù)據(jù),如果沒有傳遞引用,則可以從 GAC 中刪除所生成的程序集。

此版本的 .NET 框架需要特別注意的一點(diǎn)是:如果加載了程序集,并且使用 System.Reflection 來訪問程序集文件,則文件將在內(nèi)存中鎖定,直到進(jìn)程結(jié)束。動態(tài)生成 WSDL 以便生成代理時,將使用反射,因此對于將由客戶端進(jìn)程訪問的活動 IIS 虛擬根來說,可以鎖定程序集文件。這在運(yùn)營環(huán)境中不會產(chǎn)生問題,但是對于經(jīng)常更改組件的開發(fā)人員來說,應(yīng)該牢記這一點(diǎn)。

如果您正在使用帶有 COM+ Web 服務(wù)的 ServicedComponents,此時也需要將程序集放在 GAC 中,除非您最初將程序集放在了 bin 目錄中,并且運(yùn)行了針對該目錄中程序集的 regsvcs.exe。如果已經(jīng)加載 Microsoft .NET 框架 SDK,您可以使用 gacutil.exe 命令行實(shí)用程序,將 ServicedComponent 放入 GAC 中;如果安裝了內(nèi)置 .NET 框架的 Windows .NET Server,或者在 Windows XP 計算機(jī)上加載了可重新分發(fā)的 .NET 框架,可以使用 Microsoft .NET 框架配置用戶界面(可從 Administrative Tools 菜單訪問),將程序集添加到 GAC 中。

此外,使用 Windows XP 或 Windows .NET Server 時,請確保已安裝并配置了 IIS,以提供 ASP.NET 應(yīng)用程序服務(wù)。這些設(shè)置對于提供使用 SOAP 所必需的動態(tài)內(nèi)容是必需的。

生成的代理程序集緩存

對于要通過 .NET Remoting 發(fā)布為 SOAP 端點(diǎn)的非托管 COM+ 組件,需要生成代理,使非托管組件可用于 .NET 框架。這可以通過編程執(zhí)行與 tlbimp.exe(用于將非托管 COM+ 類型庫轉(zhuǎn)換為代理元數(shù)據(jù)程序集的 .NET 框架 SDK 工具)相同的步驟來完成。但是,要通過 SOAP 成功激活客戶端,客戶端和服務(wù)器計算機(jī)必須共享相同加強(qiáng)名稱的簽名元數(shù)據(jù)代理。因此,當(dāng)生成用于非托管 COM+ 組件的托管代理程序集時,還會生成加強(qiáng)名稱關(guān)鍵字,并用于簽名代理程序集。

加強(qiáng)名稱關(guān)鍵字只能生成一次,并且在非托管 COM+ 組件中沒有加強(qiáng)名稱關(guān)鍵字的概念。也就是說,如果多次生成代理,則可以創(chuàng)建不同的加強(qiáng)名稱關(guān)鍵字。這會為同一非托管 COM+ 組件創(chuàng)建不同的托管標(biāo)識,要避免這種情況,請將所有為非托管 COM+ 組件生成的代理程序集寫入以下 SoapCache 目錄中:

C:windowssystem32comSoapCachecomponentdirectoryproxymetdata.dll

其中 componentdirectory 的格式應(yīng)為:

ATLTrans.dll_40960_2001_6_27_15_4_16

目錄名是根據(jù)文件名、文件大小以及上次編譯的日期和時間創(chuàng)建的。此方案基于以下假設(shè):如果重新編譯非托管 COM+ 組件,則需要生成新的代理。而這又是基于以下假設(shè):如果要對代碼做出更改,只能在運(yùn)營環(huán)境中重新編譯代碼。

由于存在 SoapCache 目錄,所以如果在同一計算機(jī)的不同虛擬根發(fā)布了相同的非托管組件,而不是生成代理程序集,則位于緩存中的非托管組件將被重新使用。這是為了確保組件的加強(qiáng)名稱簽名(以及由此生成的標(biāo)識)可以通過虛擬根共享。

如果將 SOAP 啟用的非托管 COM+ 組件作為服務(wù)器應(yīng)用程序?qū)С?,然后?dǎo)入到其他服務(wù)器,緩存的代理元數(shù)據(jù)將被一起帶走,因此不同的服務(wù)器可以共享相同的非托管程序集的同一托管標(biāo)識。此外,如果用戶要生成或編寫并簽名自己的代理,只需將元數(shù)據(jù)放入相應(yīng)的緩存目錄中,當(dāng)服務(wù)器上發(fā)生 SOAP 發(fā)布時就會使用此元數(shù)據(jù)。這里應(yīng)用的基本規(guī)則是,為避免不必要地擴(kuò)散用于同一非托管組件的已簽名的代理,如果緩存中存在可替代的文件則不生成程序集。

客戶端配置

客戶端的配置工作也是必需的,最簡單的情況(至少從用戶的工作量來說)就是本文給出的第一個程序示例:

set SoapObj =
   GetObject("soap:wsdl=http://www.xmethods.net/sd
                   /TemperatureService.wsdl")
WScript.Echo "Fairbanks  氣溫 = " & SoapObj.getTemp("99707")

當(dāng)處理 WSDL 名字對象時,將會引發(fā)以下步驟:

進(jìn)行檢查,查看是否存在以前為此 URL 生成的代理。如果存在,則再次使用。(跳到步驟 4。)

如果不存在,則從 URL 檢索 WSDL 并生成 C# 代理程序。這實(shí)質(zhì)上與 soapsuds.exe 命令行實(shí)用程序(.NET 框架 SDK 所附帶的)使用的邏輯相同。
C# 程序被編譯為 DLL 并以與 URL 相匹配的名稱命名(非法字符轉(zhuǎn)換為文件名中可接受的字符)。

然后,生成的代理用于通過 .NET Remoting (WKO) 與 WSDL 中指定的遠(yuǎn)程服務(wù)器通信。
這些代理生成并保存在以下文件夾中:

C:windowssystem32comSoapAssembly

在客戶端激活的情況中,客戶端代理導(dǎo)入客戶端計算機(jī)上所必需的已導(dǎo)出的 COM+ 應(yīng)用程序。此應(yīng)用程序的導(dǎo)出/導(dǎo)入將從服務(wù)器帶來客戶端激活所必需的已簽名的元數(shù)據(jù)程序集。導(dǎo)入過程還生成配置文件,并放入 SoapAssembly 目錄中。通??蛻舳伺渲梦募捎靡韵赂袷剑?/FONT>

<configuration>
 <system.runtime.remoting>
  <application>
   <client url="
http://MyServer/VB6Soap">
    <activated type="VB6SoapSoapLib.CalcClass, VB6SoapSoapLib"/>
   </client>
  </application>
 </system.runtime.remoting>
</configuration>

COM+ Web 服務(wù)在激活組件前讀取此配置文件,這樣便可以通過修改或替換此配置文件,在客戶端計算機(jī)上潛在更改激活模型。

一切才剛剛開始

COM+ Web 服務(wù)的設(shè)計目的是簡化結(jié)合 .NET Remoting 和 COM+ 服務(wù)(Windows XP 和 Windows .NET Server 系列均包含此服務(wù))的過程。它只是為了簡化常見的任務(wù),并非包含所有的選項或涵蓋用戶可能遇到的各種情況。與使用向?qū)г?Visual Studio .NET 中創(chuàng)建程序類似,某些高級的任務(wù)留給用戶自行解決。為了使用戶可以擴(kuò)展,生成的項目很少被完全刪除。此外,XML 類用于編輯生成的配置文件,如果已經(jīng)存在配置文件,則會在該文件中添加或刪除節(jié)點(diǎn),以反映來自組件服務(wù)管理工具或 Microsoft COM+ 管理 SDK 的更改。COM+ Web 服務(wù)的設(shè)計使用戶可以輕松地擴(kuò)展或自定義已經(jīng)生成的內(nèi)容。

總之,COM+ Web 服務(wù)為現(xiàn)有的 Visual Basic 和 Visual C++ COM+ 組件,以及在 Visual Basic .NET 和 C# 中編寫的新托管的 ServicedComponents,提供了一條實(shí)現(xiàn) XML Web Services 和 SOAP 的簡單途徑。

發(fā)布:2007-03-25 10:27    編輯:泛普軟件 · xiaona    [打印此頁]    [關(guān)閉]
相關(guān)文章: