摘要:本文提供了 Microsoft .NET Remoting 框架的技術概述,其中包括了使用 TCP 通道或 HTTP 通道的示例。
簡介
Microsoft? .NET Remoting 提供了一種答應對象通過應用程序域與另一對象進行交互的框架。這種框架提供了多種服務,包括激活和生存期支持,以及負責與遠程應用程序進行消息傳輸的通訊通道。格式化程序用于在消息通過通道傳輸之前,對其進行編碼和解碼。應用程序可以在注重性能的場合使用二進制編碼,在需要與其他遠程處理框架進行交互的場合使用 xml 編碼。在從一個應用程序域向另一個應用程序域傳輸消息時,所有的 XML 編碼都使用 SOAP 協議。出于安全性方面的考慮,遠程處理提供了大量掛鉤,使得在消息流通過通道進行傳輸之前,安全接收器能夠訪問消息和序列化流。
遠程對象注冊在遠程計算機的應用程序域中。遠程對象被封送以生成 ObjRef。ObjRef 包含了從網絡上的任意位置定位和訪問遠程對象所需的所有信息,包括:類的增強名稱、類的層次結構(其父類)、類實現的所有接口的名稱、對象 URI 和所有已注冊的可用通道的具體信息。在接收到對某個遠程對象的請求時,遠程處理框架使用對象 URI 來檢索為該對象創建的 ObjRef 實例。
客戶端通過調用 new 或某個 Activator 函數(例如 CreateInstance)來激活遠程對象。對于服務器激活對象,遠程對象的 TransparentProxy 將在客戶端應用程序域中生成并返回到客戶端,這時不執行任何遠程調用。只有在客戶端調用遠程對象的某個方法時,該遠程對象才會被激活。此方案明顯不適合客戶端激活對象,因為客戶端希望框架只在得到請求時才激活對象。當客戶端調用某個激活方法時,客戶端上會創建一個激活代理,并且將使用 URL 和對象 URI 作為終結點在服務器的遠程激活器上初始化一個遠程調用。遠程激活器激活該對象,然后 ObjRef 流向客戶端,并被取消封送以生成一個返回給客戶端的 TransparentProxy。
注冊了遠程對象后,框架將為該對象創建一個對象引用,然后從程序集中提取與該對象相關的必要元數據。隨后,這一信息將與 URI 和程序集名稱一起存儲在對象引用中(該對象引用將被寫入一個用于跟蹤已注冊遠程對象的遠程處理框架表中)。請注重,除了在客戶端試圖調用對象上的某個方法或從客戶端激活對象時以外,注冊進程不會實例化遠程對象自身。
現在,任何知道該對象 URI 的客戶端都可以使用 ChannelServices 注冊通道,并調用 new、GetObject 或 CreateInstance 激活對象,從而獲得該對象的一個代理。以下代碼片斷顯示了該操作的示例:
GetObject 或 new 可用于服務器激活對象。請注重,使用這兩個調用時不會實例化對象,實際上不會生成任何網絡調用??蚣軓脑獢祿@得了創建代理所需的足夠信息,但并未連接到遠程對象上。只有在客戶端調用代理上的某個方法時才會建立網絡連接。當調用抵達服務器時,框架將從消息中提取 URI,檢查遠程處理框架表以便定位與 URI 匹配的對象引用,然后在必要時將對象實例化,并將方法調用轉發至對象。假如將對象注冊為 SingleCall,則完成方法調用后該對象會取消。每次調用一個方法時,都會創建一個新的實例。GetObject 和 new 之間的唯一差別在于,前者答應指定 URL 作為參數,而后者從配置中獲得 URL。
CreateInstance 或 new 可用于客戶端激活對象。兩者都答應使用帶參數的構造函數來實例化對象??蛻舳思せ顚ο蟮纳嫫谟蛇h程處理框架提供的租用服務控制。對象租用的內容在下一節中說明。 更多的請看:http://www.QQread.com/windows/2003/index.Html 對象的租用生存期
public class Foo : MarshalByRefObject { public override Object InitializeLifetimeService() { ILease lease = (ILease)base.InitializeLifetimeService(); if (lease.CurrentState == LeaseState.Initial) { lease.InitialLeaseTime = TimeSpan.FromMinutes(1); lease.SponsorshipTimeout = TimeSpan.FromMinutes(2); lease.RenewOnCallTime = TimeSpan.FromSeconds(2); } return lease; } } 只有當租用處于初始狀態時,才可以更改租用屬性。InitializeLifetimeService 的實現通常調用基類的相應方法,來檢索遠程對象的現有租用。假如在此之前從未對該對象封送過,則返回的租用會處于其初始狀態且可以設置租用屬性。一旦封送了對象,則租用會從初始狀態變為激活狀態,并忽略任何初始化租用屬性的嘗試(但有一種情況例外)。激活遠程對象時將調用 InitializeLifetimeService。通過激活調用可以提供一個租用發起者的列表,而且當租用處于激活狀態時,可以隨時將其他發起者添加到列表中。
可以下列方式延長租用時間:
客戶端可以調用 Lease 類上的 Renew 方法。
租用可以向某個發起者請求 Renewal。
當客戶端調用對象上的某個方法時,RenewOnCall 值會自動更新租用。 一旦租用過期,其內部狀態會由 Active 變為 EXPired,且不再對發起者進行任何調用,對象也會被作為垃圾回收。一般情況下,假如發起者分散在 Web 上或位于某個防火墻的后面,遠程對象回叫發起者時會碰到困難。因此,發起者不必與客戶端處于同一位置,只要遠程對象能夠訪問得到,它可以為網絡上的任意位置。