2)不同應用域(AppDomain),不同進程的對象之間的通信(可以使用多種通信協議)。
圖1:.NET Remoting構架圖
通常用到的Remoting的概念有:
Remoting Channel:這是指客戶端和服務器端的通信協議,如我們可以使用TCP, HTTP協議。
Serializer:這是指在傳輸時采用何種格式來傳輸數據,如我們可以采用Binary,也可以采用SOAP來傳輸XML格式的數據.
.NET力圖簡化這些概念的編程,所以上面所述的協議和格式都可以通過更改配置文件切換。這也是編程人員不用擔心的問題。如一段典型的客戶端配置文件的內容是:
<CONFIGURATION> <SYSTEM.RUNTIME.REMOTING> <APPLICATION> <CHANNELS> <CHANNEL ref="http" clientConnectionLimit="200"> <CLIENTPROVIDERS> <FORMATTER ref="binary"> </CLIENTPROVIDERS> </CHANNEL> </CHANNELS> </APPLICATION> </SYSTEM.RUNTIME.REMOTING> </CONFIGURATION> |
讓我們首先來看一個典型的實例。我們會有一個服務器程序Server.exe和一個客戶端程序CAOClient.exe?蛻舳顺绦驎ㄟ^http channel調用服務器端RemoteType.dll的對象和方法。我們會來檢查在幾種不同的Server對象下,這些調用會有什么樣不同的結果。
服務器端代碼
Server.cs using System; using System.Runtime.Remoting; public class Server{ public static void Main(string[] Args){ // Load the configuration file RemotingConfiguration.Configure("server.exe.config"); Console.WriteLine("The server is listening. Press Enter to exit...."); Console.ReadLine(); Console.WriteLine("GC'ing."); GC.Collect(); GC.WaitForPendingFinalizers(); } } |
表1:Server.cs源代碼
Server.exe.config <SYSTEM.RUNTIME.REMOTING> <APPLICATION> <SERVICE> <ACTIVATED type="ClientActivatedType, RemoteType"> </SERVICE> <CHANNELS> <CHANNEL ref="http" port="8088"> </CHANNELS> </APPLICATION> </SYSTEM.RUNTIME.REMOTING> </CONFIGURATION> |
表2:Server.exe.config源代碼
RemoteType.cs using System; using System.Runtime.Remoting.Lifetime; using System.Security.Principal; public class ClientActivatedType : MarshalByRefObject{ private int i; // override the lease settings for this object public override Object InitializeLifetimeService(){ return null; } public string RemoteMethod(){ // announce to the server that we've been called. Console.WriteLine("ClientActivatedType.RemoteMethod called."); // report our client identity name i=this.GetHashCode(); return "RemoteMethod called. " + i; } public string RemoteMethod1(){ return "RemoteMethod1 called. " + i; } } |
表3:RemoteType.cs源代碼
客戶端代碼
CAOClient.cs using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Lifetime; public class Client{ public static void Main(string[] Args){ // Load the configuration file RemotingConfiguration.Configure("CAOclient.exe.config"); ClientActivatedType CAObject = new ClientActivatedType(); Console.WriteLine("Client-activated object: " + CAObject.RemoteMethod()); Console.WriteLine("Client-activated object: " + CAObject.RemoteMethod1()); Console.WriteLine("Press Enter to end the client application domain."); Console.ReadLine(); } } |
表4 CAOClient.cs源代碼
CAOClient.exe.config <CONFIGURATION> <SYSTEM.RUNTIME.REMOTING> <APPLICATION> <CLIENT url="http://localhost:8088"> <ACTIVATED type="ClientActivatedType, RemoteType"> </CLIENT> <CHANNELS> <CHANNEL ref="http" port="0"> </CHANNELS> </APPLICATION> </SYSTEM.RUNTIME.REMOTING> </CONFIGURATION> |
表5:CAOClient.exe.config源代碼
編譯文件
使用“Visual Studio .NET Command Prompt="分別編譯上述文件:
csc /target:library RemoteType.cs csc Server.cs csc –reference:RemoteType.dll CAOClient.cs 您會看到三個輸出文件:RemoteType.dll, Server.exe 和 CAOClient.exe。 運行Remoting程序 在命令行方式下啟動:Server.exe 在命令行方式下啟動:CAOClient.exe |
程序分析
這是一個非常簡單的Remoting程序,如果去掉兩個配置文件(Server.exe.config和CAOClient.exe.config),你簡直看不到它和非Remoting的程序有什么差別。實際上,在兩個配置文件中,我們只是配置了Remoting的Channel(http:8088)。
為什么需要Remoting
我們都知道現在的Web程序都是多層架構:數據層,商業邏輯層和表示層。這樣的好處是代碼和表現的分離。這是現在程序設計一個常用的思想,XML和XSLT也是基于同樣的思想。
假設我們可以為一個程序寫兩個表示層,一個是Web Application,另一個是Windows Application,而主要的商業邏輯都放在邏輯層。如果把商業邏輯層的類和對象都作為Remoting對象,我們就可以非常方便的實現這一點。一個具體的例子是Visual Studio .NET自帶的Duwamish,這是一個非常好的例子,有很多好的設計思想。
Remoting還有很多其它的應用場景,在此就不一一闡述。
三種不同的Remoting Server對象
Remoting的Server對象有三種,每一種和客戶端的交互方式和生命周期都有一些細微的差別。在本文中,我們將為您闡述這三種Server對象之間的差別。
Client Activated 對象
這種對象在Server端的聲明方式為:
<SERVICE> <ACTIVATED type="ClientActivatedType, RemoteType"> </SERVICE> |
客戶端的聲明方式為:
。糀CTIVATED type="ClientActivatedType, RemoteType">
表6:Client Activated對象的配置文件
在這種Server端對象的調用方式下,客戶端對Server對象調用維持一個固定的鏈接,因此在兩個方法調用之間,變量I的值能夠保存。如本文表1~5代碼的返回結果是:
Client-activated object: RemoteMethod Called, 162. Client-activated object: RemoteMethod1 Called, 162. |
當然,還有一個對象生命周期的問題,如果超過了對象的生命周期,Server端的對象就會被Garbage Collection程序回收。這是一個很復雜的問題,本文不加闡述,我們只是通過下面的函數把生命周期設為無限。
public override Object InitializeLifetimeService(){ return null; } |
如果對Server端對象的生命周期有興趣的話,可以參考:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconlifetimeleases.asp Single Call 對象 |
這種對象在Server端的聲明方式為:
<SERVICE> <WELLKNOWN mode="SingleCall" type="ClientActivatedType, RemoteType" objectUri="RemoteType.rem"> </SERVICE> |
客戶端的聲明方式為:
<CLIENT url="http://localhost:8088"> <WELLKNOWN type="ClientActivatedType, RemoteType" url="HTTP://localhost:8088/RemoteType.rem"> </CLIENT> |
表7:Single Call對象的配置文件
在這種Server端對象的調用方式下,客戶端對Server對象的每次調用產生一個新的連接,因此在兩個方法調用之間,變量I的值不能夠保存。如本文表1~5代碼的返回結果是:
Client-activated object: RemoteMethod Called, 78. Client-activated object: RemoteMethod1 Called, 0. |
Singleton對象
這種對象在Server端的聲明方式為:
<SERVICE> <WELLKNOWN mode="Singleton" type="ClientActivatedType, RemoteType" objectUri="RemoteType.rem"> </SERVICE> |
客戶端的聲明方式為:
<CLIENT url="http://localhost:8088"> <WELLKNOWN type="ClientActivatedType, RemoteType" url="HTTP://localhost:8088/RemoteType.rem"> </CLIENT> |
表7:Single Call對象的配置文件
在這種Server端對象的調用方式下,無論有幾個客戶端,永遠都只有一個Server端對象。如本文表1~5代碼的返回結果是:
Client-activated object: RemoteMethod Called, 78. Client-activated object: RemoteMethod1 Called, 78. |
這時,如果另外有一個客戶端也啟動:CAOClient.exe,返回結果也是:
Client-activated object: RemoteMethod Called, 78. Client-activated object: RemoteMethod1 Called, 78. |
三種對象的簡單比較
從上面的比較中我們可以看出,在三種Server端對象中,Singleton的效率最高,但是所有客戶端的調用都只能維持一個Server對象;Client Activated的效率最低,但是它對Remoting的屏蔽最好,就像本地調用對象一樣。您可以根據不同的使用場景選擇不同的Remoting對象。
Remoting和Web Service區別
Remoting和Web Servcie到底有什么樣的差別呢?下表是一個簡單的比較:
由于Web Service是一個簡單的松耦合結構,所以對于對象的狀態不予保存。這一點有點像Remoting中的Single Call對象。同樣,Web Service目前還不支持Event和回調函數。相比較來說,Remoting還支持效率較高的Binary編碼方式。
但是,Remoting只能夠運行在.NET Framework之上,而Web Service相應就享有更多、更靈活的選擇。
文章來源于領測軟件測試網 http://www.kjueaiud.com/