范文廣,黃存東
(安徽國防科技職業學院,安徽 六安 237011)
隨著計算機的發展,特別是軟件技術的開發,對開發人員的開發效率要求越來越高,而傳統的開發工具和技術存在較大的限制,.NET是專門為程序員設計,具有很強大的功能,在此平臺上開發應用程序將變的非常容易。.NET Framework[1]是.NET的精髓,在.NET Framework中所創建的對象不可避免地將同其他主機上的對象通信,在此過程體系結構中都要通過Remoting來實現。
在.NET Framework中,對象與對象之間或進程與進程之間相互通信[2]的方式是Remoting。在調用系統服務提供的方法時,不能把所有的服務導入應用程序且運行它的一個方法,而是通過調用請求,按照一定的規則插入正在運行的進程,這樣才能使對象的運行保持安全、有效。
進程之間的通信是由多種線程模型和調度機制來完成,在分布式應用中,進程邊界問題會大量增加,通過向應用服務器調度一個線程時,必須遵守一定的規則獲得對象的訪問權,同時按照一定的方式包裝對象以便傳送。在.NET[3]中,對于邊界問題的處理通過應用程序域去實現,通過.NET Remoting提供的服務會使不同應用程序域中的對象相互交互和通信。通信選項的設置可以在配置文件中進行控制,一般可以選用TCP/IP、HTTP或其他任何一種傳輸協議;選用XML/SOAP或其他通用的串行化格式;可以通過服務器或客戶機激活對象。
通道是一種消息傳輸機制,是通過設置一定的協議和格式實現遠程應用程序與.NET Framework之間對話,是通道接收器的集合,又稱之為接收器鏈,它為信息的傳送和接收提供特殊的協議。.NET Framework為我們提供了兩個完整的通道:TcpCHannel和HttpCHannel,它們分別在Tcp和Http命名空間中,可供服務器和客戶端收發消息使用,可在對象中使用這類型而不必考慮通道接口的細節。
若要利用Remoting進行通信,就必須有可用的通道,.NET Framework通過Configuration類來處理通道的注冊。在服務器和客戶端對象的通信過程中,若客戶端應用程序要從服務器對象返回一個對象或值時,就必須注冊一個客戶端偵聽通道并與服務器使用的通道相兼容,使用相同格式化接收器和協議,使消息串行化和解串。通道注冊的端口往往是唯一的,它們的結合也形成了一個唯一傳輸路徑。
應用程序域[4]是整個Framework內的隔離機制,是為應用程序設立的執行邊界,在不同域的對象之間通信和調用對象時,必然要用Remoting使得通信和調用順利進行,如同操作系統中的進程隔離。在一個應用程序域中可以有多個進程,其本身可作為一個邏輯進程,在有托管代碼的地方使用隔離。
應用程序域通常用在不同服務器間通信的時候和出于安全原因,前者主要是不同物理服務器創建的對象不能存于同一個域中,后者是一個應用程序失敗不會導致其他應用程序失敗,在邏輯進程之外也不能復制對象的內部狀態,不會影響域外的其他對象。一般可以通過System.AppDomain類來配置應用程序域,域的邊界可由.NET Framework運行主機如ASP.NET、internet Explorer等進行設置。
在服務器和客戶端進行通信過程中,當調用遠程對象的方法時,需要在客戶端配置一個合適的通道來實現,比如:

注冊完通道后,可以在配置文件中通過指定的URI的方法來訪問遠程對象。

通道注冊完并請求對象后,在遠程運行時將在客戶端應用程序域中創建一個代理,遠程系統將處理發送給對象的信息,經過格式化接收器串行化[1]后,在通道中傳送,這些信息通過服務器格式化接收器解串,按來時的路徑回送返回值。具體過程如圖1所示。

圖1 Remoting過程中涉及的對象
遠程對象一般可通過服務器或客戶端兩種方式激活,根據激活方式的不同來決定對象的位置以及其生存期,他們的主要區別是,創建對象的時間和對象的生存期。
服務器激活對象是指對象的生存期是由服務器上的主機服務來控制,只有在客戶端發出方法調用請求時才被激活。其中主機服務是為某個或多個庫的集合充當主機角色的應用程序,對象的創建方法是由客戶端配置所控制。客戶端配置了Well-Known對象時并且是服務器激活的,在客戶端有兩種對象引用的方法,一種是用Activator.GetObject調用:


這兩種引用都依賴于使SimpleLibrary對象在指定的終點可用的本地引用的類型信息,因此無論Well-Known配置使用new操作符,還是在客戶端使用GetObject時,都要從已知類型創建一個本地代理而無須向服務器發出請求,從而不能在遠程對象上使用參數化的構造函數。
客戶端激活對象的生存期由客戶端控制,是在對象引用時向服務器發出請求以創建對象的實例,服務器上的對象會在客戶端對象調用完后自動銷毀。客戶端在向同一個對象發出請求后,會收到該對象的新實例,這時我們可以調用RemotingConfiguration.RegisterActivatedClientType來把遠程對象設置成客戶端激活對象,該調用要使用對象類型及其URI。

在此調用中,沒有服務器的類型名稱,因為在服務器上注冊客戶端激活時無須調用一個終點。為使服務器根據客戶端的請求激活對象,必須使用RemotingConfiguration.RegisterActivatedServiceType而不是Wellknown類型。

服務器激活對象是通過配置為Singletons或SingleCall對象來控制其生存期[5]。SingleCall對象是在客戶端第一次調用時創建的,當返回后就銷毀。Singletons則是由一個方法調用創建的,其生存期在服務器上是可以配置的,無論對象有沒有使用,它都會生存到其租借期結束為止。租借期作為對象上的租借時間,可以由對象創建者設置,或由對象自己設置,在租借期過期后將由無用單元回收器回收,在租借期內被使用的話,對象可以續借新的租借時間。
Well-Know類型可以由主機服務配置租借期,也可自己控制其生存期。一般在機器配置文件中,第一次激活為30秒,租借期過期前再次請求是2秒鐘;客戶端激活租借期是通過RemotingServicee.GetLifetimeService來獲得租借期引用。
在.NET Framework中,Remoting Framework處理遠程對象間的交互。客戶端通過一定的通道和終點URI向遠程對象發出請求,此時由Remoting為客戶端創建引用,并可以使用服務器激活或客戶端激活方式,前者可以在已注冊的Well-known類型[6]上用new操作符創建,也可用GetObject創建基于本地注冊類型的代理來實現;后者可通過new操作符或CreateInstance來獲取客戶端激活對象。
[1]Kevin Hoffman.NET Framework高級編程[M].北京:清華大學出版社,2002.
[2]李乃乾.NET Remoting及其在證券實時分析系統中的應用[J].計算機與數字工程,2010(1):164-189.
[3]葉嵩.基于Web技術的協同辦公系統設計[M].成都:電子科技大學出版社,2005.
[4]欒成軍,譚聞捷.基于Remoting設計安全的數據庫系統[J].電腦知識與技術,2008(7):1191-1194.
[5]王翔.基于.NET Remoting的CNG管理系統的設計與實現[J].計算機系統應用,2009(5):5-8.