回顧.NET Remoting分佈式開發

記得在下第一次接觸.NET Remoting分佈式開發是在2003年,那時候是Framework1.0初次亮相之時,Remoting分佈式開發是Framework1.0其中一個亮點。經過多年的發展,在2005年,WCF隨着Framework2.0首先亮相。WCF是結合Remoting,Web服務,TCP/IP套接字,MSMQ信息,P2P,WSE等多方通訊的混合體。隨着WCF的出現是否意昧着Remoting即將沒落,答案是否定的。因爲Remoting有其獨到之處,在通訊效率,信息交換,安全性等多方面都有其特點,所以在企業內部系統的信息化交換層的開發當中,很多時候會使用Remoting進行開發,在下面幾章爲大家回顧一下Remoting的開發。

一、基礎概念

Remoting是採用分佈式進行編程的一種技術,主要用於管理跨應用程序域的同步和異步RPC 會話。在默認情況下,Remoting可從使用 HTTP 或 TCP 協議進行信息通訊,並使用 XML 編碼的 SOAP 或二進制消息格式進行數據交換。.NET Remoting 提供了非常靈活和可擴展的編程框架,並且可以管理對象的狀態。Remoting跟Web服務不同,它並不依賴於IIS,用戶可以自己開發(Development)並部署(Dispose)宿主服務器,只需要服務器支持Framework。

二、Remoting的特點

Remoting可以靈活的定義其所基於的協議,比如http,tcp等。在使用TCP/IP的時候,Remoting能發揮更高的效率,其性能接近於DCOM。

Remoting一般需要通過一個應用程序或是Windows服務來承載,也可以使用iis部署。

Remoting必須要在一個支持Framework的開發環境下進行開發,無論客戶端跟服務器端都必須支持Framework。

Remoting 支持許多狀態管理選項,並且可能與來自同一個用戶的多個調用相關或不相關,這取決於您選擇的對象生命週期架構。

三、利用Remoting實現分佈式開發的優點

  • 容錯性

容錯性是指一個系統在出現故障時,系統應當能及時恢復。利用Remoting實現分佈式應用開發可以建立容錯軟件系統,當某個功能發生錯誤時,不會影響整體系統的工作。使系統能夠及時維護及更新。

  • 可擴展性

可擴展性是指系統可以利用性能上的遞增處理日益增加的負載量。利用Remoting實現分佈式開發,可以將最重要的核心功能模塊放置於性能強大的幾臺主機上,把其他的功能放置於功能稍差的客戶端機上,隨着客戶的增加而加大客戶端主機的服務。這樣做可以減少開發成本,提高主體性能。

  • 易於管理

一個大型計算機管理系統是非常複雜的,可能涉及的是異地機器之間的代碼調節。利用Remoting實現分佈式開發,可以把核心的功能代碼移植到中央服務器,把頁面層,UI層等功能於客戶端實現。這樣系統的性能調節,代碼升級都可以在中央服務器裏綜合實現,而忽略對客戶端的影響。

四、Remoting體系結構

下面詳細介紹一下Remoting的體系結構,如下圖。

在客戶發送請求時可以通過Activator.GetObject()和 Activator.CreateInstance()返回一個透明代理對象。實際上透明代理就像一個遠程對象,它執行遠程對象的所有公共方法,這些方法調用真實對象的Invoke()方法,傳送包含方法調用的消息。

當消息進入Channel通道後,就會經過接收器處理。接收器包含格式接收器、通道接收器和傳輸接收器,其中格式接收器和傳輸接收器是必要的。首先格式接收器會使用SoapFormatter或BinaryFormatter的方式對傳輸的對象進行序列化,如果用戶設定了通道接收器,系統將會對其進行對應處理,最後把信息送到傳輸接收器,對應設定TCP或HTTP傳輸方式加入傳輸接收器頭。當信息發送到服務器,服務器將會根據傳輸接收器頭對信息進行處理,然後在格式化接收器中對信息進行反序列化,最後通過真實代理處理遠程對象。至於“通道接收器”的處理方式,將在後幾章爲大家進一步地介紹。

五、簡單實例

說了這麼多,下面就以一個簡單的例子說明一下Remoting的開發過程吧。

首先建立一個Model.dll,注意因爲對象要進行序列化轉化,必須對其加上Serializable特性!

  1. 代碼 
  2.  
  3. using System; 
  4. using System.Collections.Generic; 
  5. using System.Linq; 
  6. using System.Text; 
  7.  
  8. namespace Model 
  9.     [Serializable] 
  10.     public class Person 
  11.     { 
  12.         public int ID 
  13.         { 
  14.             get
  15.             set
  16.         } 
  17.  
  18.         public String Name 
  19.         { 
  20.             get
  21.             set
  22.         } 
  23.  
  24.         public int Age 
  25.         { 
  26.             get
  27.             set
  28.         } 
  29.     } 

然後建立一個可遠程調用的對象,注意遠程對象必須繼承MarshalByRefObject

  1. 代碼 
  2.  
  3. using System; 
  4. using System.Collections.Generic; 
  5. using System.Linq; 
  6. using System.Text; 
  7. using System.Runtime.Serialization.Formatters.Binary; 
  8. using System.IO; 
  9. using Model; 
  10.  
  11. namespace Manager 
  12.     //類必須繼承了MarshalByRefObject,才能進行遠程調用 
  13.     public class PersonManager:MarshalByRefObject 
  14.     { 
  15.         public List<Person> GetList() 
  16.         { 
  17.             List<Person> personList = new List<Person>(); 
  18.             FileStream stream = new FileStream("DataSource.sour", FileMode.Open, FileAccess.Read);  //在服務器文件裏面獲取虛擬數據 
  19.             BinaryFormatter formatter = new BinaryFormatter(); 
  20.             personList=(List<Person>)formatter.Deserialize(stream);  //對虛擬數據進行反序列化獲取集合 
  21.             return personList; 
  22.         } 
  23.     } 

在一個應用程序中加載服務器端,服務器端的配置有兩種試,一是直接寫在代碼裏面。首先建立服務傳送方式,可以選擇用TcpServerChannel,也可使用HttpChannel,前者有着更高的效率。然後在ChannelService註冊此傳輸通道,最後通過RemotingConfiguration的RegisterWellKnownServiceType方法註冊遠程對象。

注意WellKonwnObjectMode可選擇爲SingleTon或者SingleCall,前者使用單體模式,每個客戶端進行訪問都會使用同一個遠程對象。後者會爲每個請求建立一個遠程對象。在這個例子裏面我們使用SingleTon單體模式。

  1. 代碼 
  2.  
  3. using System.Runtime.Remoting; 
  4. using System.Runtime.Remoting.Channels; 
  5. using System.Runtime.Remoting.Channels.Tcp; 
  6. using Model; 
  7. using Manager; 
  8.  
  9. namespace Server 
  10.     class Program 
  11.     { 
  12.         static void Main(string[] args) 
  13.         { 
  14.             //建立服務傳輸方式,可選擇TCP或者HTTP,前者更能發揮高效性 
  15.             TcpServerChannel channel = new TcpServerChannel(8089); 
  16.             //註冊通道 
  17.             ChannelServices.RegisterChannel(channel, false); 
  18.             //添加可調用的遠程對象,WellKonwnObjectMode可選擇爲SingleTon或者SingleCall 
  19.             RemotingConfiguration.RegisterWellKnownServiceType(typeof(PersonManager), "PersonTcp", WellKnownObjectMode.Singleton); 
  20.             Console.ReadKey(); 
  21.         } 
  22.     } 

第二,可以在config文件裏面實現服務器的配置,其效果與代碼實現的相同。

  1.  
  2.  
  3. <?xml version="1.0" encoding="utf-8" ?> 
  4. <configuration> 
  5.   <system.runtime.remoting> 
  6.     <application name="Server"> 
  7.       <service> 
  8.         //定義傳送模式,遠程對象類,Uri路徑 
  9.         <wellknown mode="Singleton"  type="Manager.PersonManager,Manager" objectUri="PersonUri"/> 
  10.       </service> 
  11.       <channels> 
  12.         //定義傳送通道,傳送方式和接口 
  13.         <channel ref="tcp" port="8089"/> 
  14.       </channels> 
  15.     </application> 
  16.   </system.runtime.remoting> 
  17. </configuration> 

最後在客戶端對遠程對象進行調用

  1. 代碼 
  2.  
  3. using System.Runtime.Remoting.Channels; 
  4. using System.Runtime.Remoting.Channels.Tcp; 
  5. using Model; 
  6. using Manager; 
  7.  
  8. namespace Client 
  9.     class Program 
  10.     { 
  11.         static void Main(string[] args) 
  12.         { 
  13.             //確立通道傳送方式 
  14.             ChannelServices.RegisterChannel(new TcpClientChannel(),false); 
  15.             //使用Activator.GetObject()或者Activator.CreateInstance()方法建立透明代理,控制遠程對象 
  16.             PersonManager personManager = (PersonManager)Activator.GetObject(typeof(PersonManager), "tcp://localhost:8089/PersonUri"); 
  17.             //獲取遠程數據 
  18.             List<Person> personList = personManager.GetList(); 
  19.             Console.Write(personList.Count); 
  20.             Console.ReadKey(); 
  21.         } 
  22.     } 

六、總結

上面已經爲大家介紹了一個簡單的Remoting開發實例。利用Remoting實現分佈式開發,可以對遠程對象的生命週期進行管理,利用HttpChannel,HttpServerChannel,HttpServerTransportSink,HttpClientChannel,HttpClientTransportSinkProvider,HttpClientTransportSink等對象控制服務器端和客戶端的通道,使用代理、消息接收器與通道接收器對信息進行管理,在下面幾章將爲各位一一介紹。

原代碼下載

 

遠程對象相互調用相關文章:

回顧.NET Remoting分佈式開發

JAVA RMI遠程方法調用簡單實例

利用JNBridge橋接模式實現遠程通訊

對.NET Remoting開發有興趣的的朋友歡迎加入QQ羣:162338858 點擊這裏加入此羣

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章