明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

Microsoft .NET Romoting 框架簡介

[摘要]Microsoft .NET Romoting 框架簡介 Paddy Srinivasan Microsoft Corporation 2001 年 1 月 摘要:本文介紹 Microsoft .N...
Microsoft .NET Romoting 框架簡介
Paddy Srinivasan
Microsoft Corporation
2001 年 1 月

摘要:本文介紹 Microsoft .NET Romoting 框架的基本原理。除了介紹組成 .NET Romoting 框架的主要組件外,還介紹 .NET Remoting 與分布式對象通信的幾種方案。

目錄
簡介
.NET Remoting 對象
集成 .NET Remoting 對象
.NET Remoting 元數(shù)據(jù)和配置文件
.NET Remoting 方案
總結(jié)
其他資料
簡介
Microsoft® .NET Remoting 是一個豐富的、可擴展的框架,它使得處于不同 AppDomain、不同過程和不同機器上的對象可以實現(xiàn)無縫通信。.NET Remoting 提供的編程模型和運行時支持功能強大而又易于使用,能夠?qū)崿F(xiàn)透明的交互操作。本文將瀏覽 Remoting 體系結(jié)構(gòu)的不同構(gòu)造塊,并研究一些應用 .NET Remoting 的常見方案。.NET Remoting 對象可以作為一種 Web 服務使用(請參閱 MSDN Magazine 文章“可編程 Web:Web 服務為 Microsoft .NET 框架提供構(gòu)造塊(英文)”,允許從任何能夠執(zhí)行 SOAP 調(diào)用的客戶端訪問 .NET Remoting 對象。有關(guān) .NET Remoting 的概述信息,請先閱讀文章“Microsoft .NET Remoting:技術(shù)概述(英文)”。

.NET Remoting 對象
有三類對象可以被配置為 .NET 遠程對象。您可以根據(jù)應用程序的需要選擇對象類型。本節(jié)將詳細介紹這些對象。

“單一調(diào)用對象”僅為一個請求提供服務。在需要對象完成的工作量有限,并且不必存儲狀態(tài)信息的情況下,單一調(diào)用對象非常有用。單一調(diào)用對象可以被配置為負載平衡模式。在方法調(diào)用之間,單一調(diào)用對象不能保留狀態(tài)信息。

“單一元素對象”可以為多個客戶端提供服務,因此可以通過保存客戶端調(diào)用的狀態(tài)信息來實現(xiàn)數(shù)據(jù)共享。當客戶端需要明確地共享數(shù)據(jù),并且不能忽略創(chuàng)建和維護對象的開銷時,這種對象非常有用。

“客戶端激活的對象 (CAO)”是服務器端的對象,收到來自客戶端的請求時會激活這些對象。這種激活服務器對象的方法與傳統(tǒng)的 COM coclass 激活方法很相似。當客戶端使用“new”操作符請求服務器對象時,將向遠程應用程序發(fā)送一個激活請求消息。隨后,服務器將創(chuàng)建被請求類的實例,并向調(diào)用它的客戶端應用程序返回 ObjRef?蛻舳藢⑹褂么 ObjRef 創(chuàng)建代理。客戶端的方法調(diào)用將在代理上執(zhí)行。客戶端激活的對象可以為其特定的客戶端(不能跨越不同的客戶端對象)保存方法調(diào)用之間的狀態(tài)信息。每次“new”調(diào)用都會返回服務器類型的獨立實例的代理。

使用 .NET Remoting 傳遞對象
在 .NET Remoting 中,可以通過以下方式在應用程序之間傳遞對象:

作為方法調(diào)用的參數(shù)
示例:public int myRemoteMethod (MyRemoteObject myObj)

方法調(diào)用的返回值
示例:public MyRemoteObject myRemoteMethod(String myString)

訪問 .NET 組件的屬性或字段得到的值
示例:myObj.myNestedObject

對于 Marshal By Value (MBV) 的對象,當它在應用程序之間傳遞時,將創(chuàng)建一個完整的副本。

對于 Marshal By Reference (MBR) 的對象,當它在應用程序之間傳遞時,將創(chuàng)建該對象的引用。當對象引用 (ObjRef) 到達遠程應用程序后,將轉(zhuǎn)變成“代理”返回原始對象。

簡單 .NET Remoting 服務器對象的代碼示例
using System;
using System.Runtime.Remoting;
namespace myRemoteService
{
// 有名的 Web 服務對象
public class myRemoteObject : MarshalByRefObject
{
// myRemoteMethod 方法
public String myRemoteMethod(String s)
{
return "Hello World";
}
}
}

訪問此對象的客戶端代碼示例
using System;
using System.Runtime.Remoting;
using myRemoteService;
public class Client
{
public static int Main(string[] args)
{
ChannelServices.RegisterChannel(new HTTPChannel(7055));
// 創(chuàng)建 myRemoteObject 類的實例
myRemoteObject myObj = ( myRemoteObject)Activator.GetObject(typeof(myRemoteObject),
"http://myHost:7021/host/myRemoteObject.soap");
myObj. myRemoteMethod ("Hello World");
return 0;
}
}
租用生存期
對于那些具有在應用程序之外傳送的對象引用的對象,將創(chuàng)建一個租用。租用具有一個租用時間。如果租用時間為 0,則租用過期,對象將斷開與 .NET Romoting 框架的連接。一旦 AppDomain 內(nèi)部所有的對象引用都被釋放,則下一個 GC 發(fā)生時對象將被回收。租用控制了對象的生存期。

對象有默認的租用階段。當客戶端要在同一服務器對象中維護狀態(tài)信息時,可以通過許多方法擴展租用階段,使對象繼續(xù)生存。

可以將服務器對象的租用時間設置為無限,這樣 Remoting 在垃圾回收周期中就不會回收此對象。


客戶端可以調(diào)用 RemotingServices.GetLifetimeService 方法,以從 AppDomain 的租用管理器獲取服務器對象的租用時間。然后,客戶端便可以通過 Lease 對象來調(diào)用 Lease.Renew 方法,以延長租用時間。


客戶端可用 AppDomain 的租用管理器為特定的租用注冊負責人。當遠程對象租用過期時,租用管理器將通知負責人提出更新租用的申請。


如果設置了 ILease::RenewOnCallTime 屬性,則每次調(diào)用遠程對象時,都會用 RenewOnCallTime 屬性指定的時間更新租用時間。
單一調(diào)用/單一元素對象 客戶端激活的對象
客戶端激活代碼(客戶端所需的代碼)
有關(guān)詳細信息,請參閱配置文件的相關(guān)小節(jié)
a) Activator.GetObject()
b) new() 及 CFG 文件

客戶的 CFG 文件引用下列 URL:

Foo= http://localhost:80/ObjectZone/Foo.soap
a) Activator.CreateInstance()
b) new() 及 CFG 文件

客戶的 CFG 文件引用服務器數(shù)據(jù)庫以及服務器應用程序的 URL,并提供對象 URI?蛻舳藘(nèi)置了對這些數(shù)據(jù)庫的引用:

Assembly#MyObjectLibrary#ObjectZone#
MyObjectLibrary.Baz

RemoteApplication#ObjectZone#
HTTP://localhost:80/ObjectZone

服務器對象的激活 在首次調(diào)用方法之前,不會在網(wǎng)絡上發(fā)送激活消息 當客戶端創(chuàng)建對象,并且在客戶端生成代理之后,激活消息將發(fā)送至服務器。支持帶參數(shù)的構(gòu)造函數(shù)。
服務器對象的生存期 生存期由服務器上的配置設定,可以為 SingleCall 或 Singleton 生存期在下列兩個事件之一發(fā)生時結(jié)束:
a) 租用過期

b) 客戶釋放在服務器對象上的引用時

服務器端注冊 a) 使用配置文件來指定類型(SingleCall 或 Singleton)
b) 使用 RegisterWellKnownType() API 注冊類型
使用配置文件來導出客戶端激活的對象
有關(guān)詳細信息,請參閱配置文件的相關(guān)小節(jié)

模型的優(yōu)點 a) 可以利用服務器組件的基類或接口定義公共語言運行時元數(shù)據(jù)來編譯客戶端
b) 在服務器端執(zhí)行有限操作的情況下很有用處

c) 單一調(diào)用對象不保存狀態(tài)信息,所以易于在負載平衡系統(tǒng)中進行配置

d) 單一元素對象可以在多個客戶對象之間維護狀態(tài)信息
a) 服務器對象的調(diào)用與傳統(tǒng)的 COM“coclass”類似
b) 客戶端可以更加靈活地管理服務器對象的生存期

c) 客戶端能夠向被創(chuàng)建的對象傳遞構(gòu)造函數(shù)參數(shù)

d) 服務器對象可以為其特定客戶端在多次方法調(diào)用之間保留狀態(tài)信息

集成 .NET Remoting 對象
.NET Remoting 對象可以集成在:

托管可執(zhí)行項:.NET Remoting 對象可以集成在任何常規(guī)的 .NET EXE 或托管服務中。


IIS:Remoting 對象可以集成在 Internet Information Server (IIS) 中。默認情況下,集成在 IIS 中的 Remoting 對象通過 HTTP 通道接收消息。要在 IIS 中集成 Remoting 對象,必須創(chuàng)建一個虛擬根目錄,并將 remoting.cfg 文件復制到其中。包含遠程對象的可執(zhí)行文件或 DLL 應放置在 IIS 根目錄下的 bin 目錄中。需要注意的是,IIS 根目錄的名稱應該與配置文件中指定的應用程序名稱相同。當應用程序接收到第一個消息時,遠程配置文件將自動加載。使用這種方法,可以將 .NET Remoting 對象作為 Web 服務提供。
Remoting.cfg 文件示例:

Name#HelloService
WellKnownObject#HelloService.Hello#HelloService#HelloService/
Hello.soap#SingleCall

其格式為:
Name#[Name of the Application]
WellKnownObject#[FullTypeName]#[AssemblyName]#[ObjectURI]#[ObjectMode]
.NET 組件服務:.NET Remoting 對象可以集成在 .NET 組件服務基礎(chǔ)結(jié)構(gòu)中,從而利用各種 COM+ 服務,例如:事務、JIT、對象池等。
有關(guān)詳細信息,請參閱 Microsoft .NET 框架組件服務,第 1 部分(英文)。

通道服務 (System.Runtime.Remoting.Channels)
.NET 應用程序和 AppDomains 之間使用消息進行通信。.NET “通道服務”為這一通信過程提供了底層傳輸機制。

.NET 框架提供了 HTTP、TCP 和 SMTP 通道,但是第三方也可以編寫并使用自己的通道。默認情況下,HTTP 和 SMTP 通道使用 SOAP 進行通信,而 TCP 通道使用二進制有效負載。

通過使用可以編寫到集成混合應用程序中的自定義通道,可以插入通道服務(使用 IChannel)。

加載通道服務的代碼示例
public class myRemotingObj
{
HTTPChannel httpChannel;
TCPChannel tcpChannel;
public void myRemotingMethod()
{
httpChannel = new HTTPChannel();
tcpChannel = new TCPChannel();
ChannelServices.RegisterChannel(httpChannel);// 注冊 HTTP 通道
ChannelServices.RegisterChannel(tcpChannel);// 注冊 TCP 通道


}
}

序列化格式化程序 (System.Runtime.Serialization.Formatters)
.NET 序列化格式化程序?qū)?.NET 應用程序和 AppDomains 之間的消息進行編碼和解碼。在 .NET 運行時中有兩個本地格式化程序,分別為 Binary (System.Runtime.Serialization.Formatters.Binary) 和 SOAP (System.Runtime.Serialization.Formatters.Soap)。

序列化格式化程序是可插入的,方法是實例化 IRemotingFormatter 接口,并將其插入到上文介紹的通道中。這樣,您可以靈活地選擇通道和格式化程序的組合方式,采用最適合應用程序的方案。本文后面的小節(jié)將討論這一問題。

例如:您可以采用 HTTP 通道和 Binary 格式化程序(串行化二進制數(shù)據(jù)),也可以采用 TCP 通道和 SOAP 格式化程序。

Remoting 上下文
“上下文”是一個包含共享公共運行時屬性的對象的范圍。一些有關(guān)上下文屬性的例子是與同步和線程緊密相關(guān)的。當 .NET 對象被激活時,運行時將檢查當前的上下文是否一致,如果不一致,將創(chuàng)建新的上下文。多個對象可以同時在一個上下文中運行,并且一個 AppDomain 中可以有多個上下文。

一個上下文中的對象調(diào)用另一個上下文中的對象時,調(diào)用將通過上下文代理來執(zhí)行,并且會受組合上下文屬性的強制策略影響。新對象的上下文通常是基于類的元數(shù)據(jù)屬性選擇的。

可以與上下文綁定的類稱作上下文綁定類。上下文綁定類可以具有稱作“上下文屬性”的專用自定義屬性。上下文屬性是完全可擴展的,您可以創(chuàng)建這些屬性并將它們附加到自己的類中。與上下文綁定的對象是從 System.ContextBoundObject 導出的。

.NET Remoting 元數(shù)據(jù)和配置文件
.NET 框架使用元數(shù)據(jù)和程序集來存儲有關(guān)組件的信息,使得多語言編程技術(shù)成為可能。.NET Remoting 使用元數(shù)據(jù)動態(tài)地創(chuàng)建代理對象。在客戶端創(chuàng)建的代理對象的成員與原始類相同。但是,代理對象的實現(xiàn)僅僅將所有的請求通過 .NET Remoting 運行時轉(zhuǎn)發(fā)給原始對象。序列化格式化程序使用元數(shù)據(jù)將方法調(diào)用轉(zhuǎn)換為有效負載數(shù)據(jù)流,并將有效負載數(shù)據(jù)流轉(zhuǎn)換回方法調(diào)用。

客戶端可以通過以下方法獲取訪問遠程對象所需的元數(shù)據(jù)信息:

服務器對象的“.NET 程序集”- 服務器對象可以創(chuàng)建元數(shù)據(jù)程序集,并將其分發(fā)給客戶端。在編譯客戶端對象時,客戶端對象可以引用這些程序集。在客戶端和服務器都是托管組件的封閉環(huán)境中,這種方法非常有用。


遠程對象可以提供 WSDL(請參閱 Web 服務說明語言 [WSDL] 1.0 [英文])文件,用于說明對象及其方法。所有可以根據(jù) WSDL 文件讀取和生成 SOAP 請求的客戶端都可以調(diào)用此對象,或使用 SOAP 與之通信。使用與 .NET SDK 一同分發(fā)的 SOAPSUDS.EXE 工具,.NET Remoting 服務器對象可以生成具有元數(shù)據(jù)功能的 WSDL 文件。當組織希望提供所有客戶都能訪問和使用的公共服務時,這種方法非常有用。


.NET 客戶可以使用 SOAPSUDS 工具從服務器上下載 XML 架構(gòu)(在服務器上生成),生成僅包含元數(shù)據(jù)(沒有代碼)的源文件或程序集。您可以根據(jù)需要將源文件編譯到客戶端應用程序中。如果多層應用程序中某一層的對象需要訪問其他層的遠程對象,則經(jīng)常使用此方法。
“配置文件”(.CFG 文件)用于指定特定對象的各種 Remoting 特有信息。通常情況下,每個 AppDomain 有自己的 CFG 文件。使用 CFG 文件有助于實現(xiàn)位置的透明性。CFG 文件中的詳細信息也可以通過編程來指定。使用 CFG 文件的主要好處在于,它將與客戶端代碼無關(guān)的配置信息分離出來,這樣,在日后更改時僅需要修改 CFG 文件,而不用編輯和重新編譯源代碼。.NET Remoting 的客戶端和服務器對象都使用配置文件。

典型的 CFG 文件包含以下信息及其他信息:

集成應用程序信息


對象名稱


對象的 URI


注冊的通道(可以同時注冊多個通道)


服務器對象的租用時間信息
示例配置文件(請注意,在后續(xù)版本中可能會采用 XML 格式):

Name#MyRemoteApp
myRemoteObj = HTTP://myCompany:80/MyRemoteApp/myRemoteObj.soap
Channel#System.Runtime.Remoting#System.Runtime.Remoting.Channels.TCP.TCPChannel
Channel#System.Runtime.Remoting#System.Runtime.Remoting.Channels.HTTP.HTTPChannel
.NET Remoting 方案
了解 .NET Remoting 如何工作之后,讓我們來考察不同的方案,分析如何在不同的方案中充分發(fā)揮 .NET Remoting 的性能。下表列出了可能的客戶端/服務器組合,以及默認情況下采用的底層協(xié)議和有效負載。請注意,.NET Remoting 框架是可擴展的,您可以編寫自己的通信通道和序列化格式化程序。

客戶端 服務器 有效負載 協(xié)議
.NET 組件 .NET 組件 SOAP/XML http
.NET 組件 .NET 組件 二進制 TCP
托管/非托管 .NET Web 服務 SOAP/XML http
.NET 組件 非托管的傳統(tǒng) COM 組件 NDR(網(wǎng)絡數(shù)據(jù)表示形式) DCOM
非托管的傳統(tǒng) COM 組件 .NET 組件 NDR DCOM


任何客戶端 <-> .NET,使用 HTTP-SOAP
Web 服務是可以通過 URL 尋址的資源,并通過編程向需要使用這些資源的客戶端返回信息?蛻舳耸褂 Web 服務時不必考慮其實現(xiàn)細節(jié)。Web 服務使用稱為“合約”的嚴格定義的接口,此接口采用 Web 服務描述語言 (WSDL) 文件定義。有關(guān) WSDL 的詳細信息,請參閱 Web 服務描述語言 (WSDL) 1.0(英文)。

可以將 .NET Remoting 對象集成在 IIS 中,使它們作為 Web 服務使用。任何可以使用 WSDL 文件的客戶端,都可以按照 WSDL 文件中指定的約定對遠程對象執(zhí)行 SOAP 調(diào)用。IIS 使用 ISAPI 擴展將這些請求路由到相應的對象。這樣,遠程對象就可以作為 Web 服務對象來使用,從而充分發(fā)揮 .NET 框架基礎(chǔ)結(jié)構(gòu)的作用。如果您希望不同平臺/環(huán)境的程序均能夠訪問對象,則可以采用這種配置。有關(guān) Web 服務的詳細信息,請參閱可編程 Web:Web 服務為 Microsoft .NET 框架提供構(gòu)造塊(英文)。這種配置方法便于客戶端通過防火墻訪問您的 .NET 對象。

圖 1:通過 HTTP-SOAP 調(diào)用 Remoting 對象的 Web 服務的客戶端示例

.NET <-> .NET,使用 SOAP-HTTP 通道
默認情況下 HTTP 通道使用 SOAP 格式化程序,因此,如果客戶端需要通過 Internet 訪問對象,則可以使用 HTTP 通道。由于這種方法使用 HTTP,所以允許客戶端通過防火墻遠程訪問 .NET 對象。只需按前一節(jié)中介紹的方法將這些對象集成在 IIS 中,即可將其配置為 Web 服務對象。隨后,客戶端就可以讀取這些對象的 WSDL 文件,以便使用 SOAP 與 Remoting 對象通信。

.NET <-> .NET,使用 TCP 通道
默認情況下,TCP 通道使用二進制格式化程序。此格式化程序以二進制格式進行數(shù)據(jù)的序列化,并使用原始套接字在網(wǎng)絡中傳送數(shù)據(jù)。如果對象部署在受防火墻保護的封閉環(huán)境中,則此方法是理想的選擇。該方法使用套接字在對象之間傳遞二進制數(shù)據(jù),因此性能更好。由于它使用 TCP 通道來提供對象,因此具有在封閉環(huán)境中開銷較小的優(yōu)點。由于防火墻和配置問題,此方法不能在 Internet 上使用。

圖 2:通過 TCP 通道在多個機器之間調(diào)用 Remoting 對象的客戶端示例

.NET <-> 非托管的 COM 組件 <-> .NET
您可以通過 COM Interop Service 調(diào)用非托管的傳統(tǒng) COM 組件。當 .NET Remoting 客戶端對象創(chuàng)建 COM 對象的實例時,對象通過運行時可調(diào)用包裝程序 (RCW) 來提供,而 RCW 則作為真實非托管對象的代理。這些包裝程序看起來和 .NET 客戶端的任何其他托管類一樣,但實際上,它們僅僅是托管 (.NET) 和非托管 (COM) 代碼之間的封送調(diào)用。

類似地,您可以將 .NET Remoting 服務器對象提供給傳統(tǒng) COM 客戶端。當 COM 客戶端創(chuàng)建 .NET 對象的實例時,對象通過 COM 可調(diào)用包裝程序 (CCW) 來提供,而 RCW 則作為真實非托管對象的代理。

這兩種方案都使用 DCOM 通信。如果環(huán)境中既有傳統(tǒng)的 COM,又有 .NET 組件,那么這種互操作性將為您提供便利。有關(guān)此主題的詳細信息,請參閱 COM 互操作性規(guī)范(英文)。

總結(jié)
Microsoft .NET 框架提供了強大、可擴展、不依賴于語言的框架,用于開發(fā)可靠、可伸縮的分布式系統(tǒng)。.NET Romoting 框架提供了根據(jù)系統(tǒng)需求進行遠程交互的強大手段。.NET Remoting 實現(xiàn)了與 Web 服務的無縫集成,并有一些方法可以提供 .NET 對象以進行多平臺訪問的方法