.NET Remoting提供了一個功能強大、高效的處理遠程對象的方法,從結構上而言,.NET Remote對象非常適合通過網絡訪問資源,而又無需處理由基於SOAP的WebServices所帶來的難題。.NET Remoting使用起來比Java的RMI簡單,但要比創建Web Service難度大一些。
什么是Remoting,簡而言之,我們可以將其看作是一種分布式處理方式。從微軟的產品角度來看,可以說Remoting就是DCOM的一種升級,它改 善了很多功能,並極好的融合到.Net平台下。Microsoft? .NET Remoting 提供了一種允許對象通過應用程序域與另一對象進行交互的框架。這也正是我們使用Remoting的原因。為什么呢?在Windows操作系統中,是將應用 程序分離為單獨的進程。這個進程形成了應用程序代碼和數據周圍的一道邊界。如果不采用進程間通信(RPC)機制,則在一個進程中執行的代碼就不能訪問另一 進程。這是一種操作系統對應用程序的保護機制。然而在某些情況下,我們需要跨過應用程序域,與另外的應用程序域進行通信,即穿越邊界。
在Remoting中是通過通道(channel)來實現兩個應用程序域之間對象的通信的。首先,客戶端通過Remoting,訪問通道以獲得服務端 對象,再通過代理解析為客戶端對象。這就提供一種可能性,即以服務的方式來發布服務器對象。遠程對象代碼可以運行在服務器上(如服務器激活的對象和客戶端 激活的對象),然后客戶端再通過Remoting連接服務器,獲得該服務對象並通過序列化在客戶端運行。
在Remoting中,對於要傳遞的對象,設計者除了需要了解通道的類型和端口號之外,無需再了解數據包的格式。但必須注意的是,客戶端在獲取服務器 端對象時,並不是獲得實際的服務端對象,而是獲得它的引用。這既保證了客戶端和服務器端有關對象的松散耦合,同時也優化了通信的性能。
Remoting的兩種通道
Remoting的通道主要有兩種:Tcp和Http。在.Net中,System.Runtime.Remoting.Channel中定義了 IChannel接口。IChannel接口包括了TcpChannel通道類型和Http通道類型。它們分別對應Remoting通道的這兩種類型。
TcpChannel類型放在名字空間System.Runtime.Remoting.Channel.Tcp中。Tcp通道提供了基於 Socket 的傳輸工具,使用Tcp協議來跨越Remoting邊界傳輸序列化的消息流。TcpChannel類型默認使用二進制格式序列化消息對象,因此它具有更高 的傳輸性能。HttpChannel類型放在名字空間System.Runtime.Remoting.Channel.Http中。它提供了一種使用 Http協議,使其能在Internet上穿越防火牆傳輸序列化消息流。默認情況下,HttpChannel類型使用Soap格式序列化消息對象,因此它 具有更好的互操作性。通常在局域網內,我們更多地使用TcpChannel;如果要穿越防火牆,則使用HttpChannel。
遠程對象的激活方式
在訪問遠程類型的一個對象實例之前,必須通過一個名為Activation的進程創建它並進行初始化。這種客戶端通過通道來創建遠程對象,稱為對象的激活。在Remoting中,遠程對象的激活分為兩大類:服務器端激活和客戶端激活。
服務器端激活,又叫做WellKnow方式,很多又翻譯為知名對象。為什么稱為知名對象激活模式呢?是因為服務器應用程序在激活對象實例之前會在一個 眾所周知的統一資源標識符(URI)上來發布這個類型。然后該服務器進程會為此類型配置一個WellKnown對象,並根據指定的端口或地址來發布對 象。. Net Remoting把服務器端激活又分為SingleTon模式和SingleCall模式兩種。
SingleTon模式:此為有狀態模式。如果設置為SingleTon激活方式,則Remoting將為所有客戶端建立同一個對象實例。當對象處於 活動狀態時, SingleTon實例會處理所有后來的客戶端訪問請求,而不管它們是同一個客戶端,還是其他客戶端。SingleTon實例將在方法調用中一直維持其狀 態。舉例來說,如果一個遠程對象有一個累加方法(i=0;++i),被多個客戶端(例如兩個)調用。如果設置為SingleTon方式,則第一個客戶獲得 值為1,第二個客戶獲得值為2,因為他們獲得的對象實例是相同的。如果熟悉Asp.Net的狀態管理,我們可以認為它是一種Application狀態。
SingleCall模式:SingleCall是一種無狀態模式。一旦設置為SingleCall模式,則當客戶端調用遠程對象的方法時, Remoting會為每一個客戶端建立一個遠程對象實例,至於對象實例的銷毀則是由GC自動管理的。同上一個例子而言,則訪問遠程對象的兩個客戶獲得的都 是1。我們仍然可以借鑒Asp.Net的狀態管理,認為它是一種Session狀態。
客戶端激活。與WellKnown模式不同, Remoting在激活每個對象實例的時候,會給每個客戶端激活的類型指派一個URI。客戶端激活模式一旦獲得客戶端的請求,將為每一個客戶端都建立一個 實例引用。SingleCall模式和客戶端激活模式是有區別的:首先,對象實例創建的時間不一樣。客戶端激活方式是客戶一旦發出調用的請求,就實例化; 而SingleCall則是要等到調用對象方法時再創建。其次,SingleCall模式激活的對象是無狀態的,對象生命期的管理是由GC管理的,而客戶 端激活的對象則有狀態,其生命周期可自定義。其三,兩種激活模式在服務器端和客戶端實現的方法不一樣。尤其是在客戶端,SingleCall模式是由 GetObject()來激活,它調用對象默認的構造函數。而客戶端激活模式,則通過CreateInstance()來激活,它可以傳遞參數,所以可以 調用自定義的構造函數來創建實例。
遠程對象的定義
前面講到,客戶端在獲取服務器端對象時,並不是獲得實際的服務端對象,而是獲得它的引用。因此在Remoting中,對於遠程對象有一些必須的定義規范要遵循。
由於Remoting傳遞的對象是以引用的方式,因此所傳遞的遠程對象類必須繼承MarshalByRefObject。MSDN對 MarshalByRefObject的說明是:MarshalByRefObject 是那些通過使用代理交換消息來跨越應用程序域邊界進行通信的對象的基類。不是從 MarshalByRefObject 繼承的對象會以隱式方式按值封送。當遠程應用程序引用一個按值封送的對象時,將跨越遠程處理邊界傳遞該對象的副本。因為您希望使用代理方法而不是副本方法 進行通信,因此需要繼承MarshallByRefObject。
在Remoting中能夠傳遞的遠程對象可以是各種類型,包括復雜的DataSet對象,只要它能夠被序列化。遠程對象也可以包含事件,但服務器端對於事件的處理比較特殊,我將在本系列之三中介紹。
服務器端
根據第一部分所述,根據激活模式的不同,通道類型的不同服務器端的實現方式也有所不同。大體上說,服務器端應分為三步:
1、注冊通道
要跨越應用程序域進行通信,必須實現通道。如前所述,Remoting提供了IChannel接口,分別包含TcpChannel和 HttpChannel兩種類型的通道。這兩種類型除了性能和序列化數據的格式不同外,實現的方式完全一致,因此下面我們就以TcpChannel為例。
注冊TcpChannel,首先要在項目中添加引用“System.Runtime.Remoting”,然后using名字空間: System.Runtime.Remoting.Channel.Tcp。在實例化通道對象時,將端口號作為參數傳遞。然后再調用靜態方法 RegisterChannel()來注冊該通道對象即可。
2、注冊遠程對象
注冊了通道后,要能激活遠程對象,必須在通道中注冊該對象。根據激活模式的不同,注冊對象的方法也不同。
對於WellKnown對象,可以通過靜態方法 RemotingConfiguration.RegisterWellKnownServiceType()來實現,注冊對象的方法基本上和 SingleTon模式相同,只需要將枚舉參數WellKnownObjectMode改為SingleCall就可以了。
3、注銷通道
如果要關閉Remoting的服務,則需要注銷通道,也可以關閉對通道的監聽。在Remoting中當我們注冊通道的時候,就自動開啟了通道的監聽。 而如果關閉了對通道的監聽,則該通道就無法接受客戶端的請求,但通道仍然存在,如果你想再一次注冊該通道,會拋出異常。
如果你剛開是學 看幾個例子就行了
remoting webservice 涉及到設計模式
現在很多公司都要求使用 remoting webservice來實現 面向服務架構(SOA)
解決方案讓您更輕松地應對變更.無論您的流程多么復雜或緩慢,SOA都能夠幫助簡化它們,幫助組織實現快速變革,進而實現業務影響力.
一、Remoting的優缺點?
優點:
1、能讓我們進行分布式開發
2、Tcp通道的Remoting速度非常快
3、雖然是遠程的,但是非常接近於本地調用對象
4、可以做到保持對象的狀態
5、沒有應用程序限制,可以是控制台,winform,iis,windows服務承載遠程對象
缺點:
1、非標准的應用因此有平台限制
2、脫離iis的話需要有自己的安全機制
二、Remoting和Web服務的區別?
ASP.NET Web 服務基礎結構通過將 SOAP 消息映射到方法調用,為 Web 服務提供了簡單的 API。通過提供一種非常簡單的編程模型(基於將 SOAP 消息交換映射到方法調用),它實現了此機制。ASP.NET Web 服務的客戶端不需要了解用於創建它們的平台、對象模型或編程語言。而服務也不需要了解向它們發送消息的客戶端。唯一的要求是:雙方都要認可正在創建和使用 的 SOAP 消息的格式,該格式是由使用 WSDL 和 XML 架構 (XSD) 表示的 Web 服務合約定義來定義的。
. NET Remoting 為分布式對象提供了一個基礎結構。它使用既靈活又可擴展的管線向遠程進程提供 .NET 的完全對象語義。ASP.NET Web 服務基於消息傳遞提供非常簡單的編程模型,而 .NET Remoting 提供較為復雜的功能,包括支持通過值或引用傳遞對象、回調,以及多對象激活和生命周期管理策略等。要使用 .NET Remoting,客戶端需要了解所有這些詳細信息,簡而言之,需要使用 .NET 建立客戶端。.NET Remoting 管線還支持 SOAP 消息,但必須注意這並沒有改變其對客戶端的要求。如果 Remoting 端點提供 .NET 專用的對象語義,不管是否通過 SOAP,客戶端必須理解它們。
三、最簡單的Remoting的例子
項目DEMO截圖:
1、遠程對象:
建立類庫項目:RemoteObject
using System;
namespace RemoteObject
{
public class MyObject:MarshalByRefObject
{
public int Add(int a,int b)
{
return a+b;
}
}
}
2、服務端
建立控制台項目:RemoteServer
using System;
using System.Runtime.Remoting;
namespace RemoteServer
{
class MyServer
{
[STAThread]
static void Main(string[] args)
{
RemotingConfiguration.Configure("RemoteServer.exe.config");
Console.ReadLine();
}
}
}
建立配置文件:app.config
<configuration>
<system.runtime.remoting>
<application name="RemoteServer">
<service>
<wellknown type="RemoteObject.MyObject,RemoteObject" objectUri="RemoteObject.MyObject"
mode="Singleton" />
</service>
<channels>
<channel ref="tcp" port="9999"/>
</channels>
</application>
</system.runtime.remoting>
</configuration>
3、客戶端:
建立控制台項目:RemoteClient
using System;
namespace RemoteClient
{
class MyClient
{
[STAThread]
static void Main(string[] args)
{
RemoteObject.MyObject app = (RemoteObject.MyObject)Activator.GetObject(typeof(RemoteObject.MyObject),System.Configuration.ConfigurationSettings.AppSettings["ServiceURL"]);
Console.WriteLine(app.Add(1,2));
Console.ReadLine();
}
}
}
建立配置文件:app.config
<configuration>
<appSettings>
<add key="ServiceURL" value="tcp://localhost:9999/RemoteObject.MyObject"/>
</appSettings>
</configuration>
4、測試
在最后編譯的時候會發現編譯報錯:
1、找不到app.Add()
2、找不到RemoteObject
這是因為客戶端RemoteClient沒有添加RemoteObject的引用,編譯器並不知道遠程對象存在哪些成員所以報錯,添加引用以后 vs.net會在客戶端也保存一個dll,可能大家會問這樣如果對遠程對象的修改是不是會很麻煩?其實不麻煩,對項目編譯一次vs.net會重新復制 dll。
然后直接運行客戶端會出現“目標主機拒絕”的異常,也說明了通道沒有打開
運行服務端再運行客戶端出現“找不到程序集RemoteObject”!回頭想想可以發現我們並在服務端對RemoteObject添加引用,編譯的時候 通過是因為這個時候並沒有用到遠程對象,大家可能不理解運行服務端的時候也通過?這是因為沒有這個時候還沒有激活遠程對象。理所當然,對服務端要添加引用 遠程對象,畢竟我們的對象是要靠遠程承載的。
現在再先后運行服務端程序和客戶端程序,客戶端程序顯示3,測試成功。
四、結束語
我們通過一個簡單的例子實現了最簡單的remoting,對其實質沒有做任何介紹,我想通過例子入門才是最簡單的。
本文轉自:http://www.cnblogs.com/Leo_wl/archive/2010/05/06/1729264.html

每個人在他生活中都經歷過不幸和痛苦。有些人在苦難中只想到自己,他就悲觀消極發出絕望的哀號;有些人在苦難中還想到別人,想到集體,想到祖先和子孫,想到祖國和全人類,他就得到樂觀和自信。 ——洗星海
