.NET REMOTING 技朮(值得用這一 技朮)

一、Remoting簡介

  .NET Remoting(下文簡稱Remoting)是一種可用於開發分佈式應用程序的技術。其主要的結構,分爲:遠程對象、提供遠程對象的遠程服務器,以及可以訪問何使用遠程對象的客戶端。這三個部分,可以分佈於同一臺計算機的同一個進程,或者是不同的進程,也可以是處於網絡上的不同的計算機。Remoting技術最大的特點,就是對遠程通信的過程進行了抽象和封裝,使開發人員不必去處理底層通信的細節,而可以把重點放在對業務邏輯的處理上。而且Remoting的通信協議也比較靈活,可以使用多個通信協議、不同的數據格式類型,以及不同類型的序列化機制。在某些情況下,Remoting還允許你使用自定義的數據格式。

二、.NET Remoting與DCOM

  說到這裏,你也許會想到DCOM(分佈式組件對象模型),在以前的分佈式應用中,DCOM是一種比較高效的解決方案。和Remoting技術相比,DCOM在進行數據傳輸的時候,使用的是專有的二進制數據格式,而Remoting可以使用任意一種格式,包括二進制格式和XML格式,以及用戶自定義的數據格式。DCOM的另外一個問題,就是在網絡環境中,大部分的防火牆不允許DCOM穿過,解決的辦法是重新配置防火牆。利用Remoting,可以輕鬆的穿過防火牆,一切可以順利的進行 :)。因此,在實質上,可以認爲Remoting是DCOM針對.NET的改進版本。

三、.NET Remoting與Web Service

  運行於Internet的分佈式應用程序,Web Service是首選的解決方案,因爲Web Service能夠穿透足夠安全的防火牆,雖然Remoting技術也可以實現這樣的功能,但是對於Internet解決方案,Web Service仍是首選。和Web Service相比,Web Service需要Web服務器的支持,Remoting不需要Web服務器,它是使用自己的HTTP或者TCP服務器。在內部網絡的解決方案中,Remoting擁有足夠的優勢,當採用TCP和二進制數據傳輸的時候,能有更高的效率。不過有一點值得注意:Web Service可以跨平臺運行,而Remoting只能運行在.NET FrameWork的平臺下。

四、簡單的例子,開始我們的Remoting之旅

  講了這麼多,都是理論的東西,相信大家已經躍躍欲試了。下面我們還是按照老規矩,用一個經典的Hello World來開始我們的Remoting之旅吧!我們的例子,也是分三步開始:

建立遠程對象; 
建立遠程服務器; 
建立客戶端程序,調用遠程對象; 
準備好了嗎?Let''s go~!

首先,我們編寫遠程對象的類 


namespace RemoteObject
{
public __gc class RemoteObjClass:public MarshalByRefObject
{
public:
String * DisplayMessage()
{
return S"Hello World!";
}
};

  這是一個很簡單的類,DisplayMessage成員函數,返回一串字符:Hello World。在這裏,我們要注意MarshalByRefObject,我們的類就是從它繼承而來。在.NET中有應用程序域的概念,MarshalByRefObject類,能讓對象跨應用域被訪問。 

然後,我們來建立遠程服務器,代碼如下:
using namespace System;
using namespace System::Runtime::Remoting;
using namespace System::Runtime::Remoting::Channels;
using namespace System::Runtime::Remoting::Channels::Tcp;
using namespace RemoteObject;

int _tmain()
{
// TODO: 請用您自己的代碼替換下面的示例代碼。
TcpChannel *Channel=new TcpChannel(8888);
ChannelServices::RegisterChannel(Channel);
RemotingConfiguration::RegisterWellKnownServiceType(
Type::GetType(
"RemoteObject.RemoteObjClass,RemoteObject"),
S"Test",WellKnownObjectMode::SingleCall);

Console::WriteLine(S"Server is running...");
Console::ReadLine();
return 0;

(注:服務端和客戶端,由於用到Remoting相關的類,所以需要在工程中,添加對System.Runtime.Retmoting的引用)
服務器和客戶端之間的通信,是藉由通道來實現的。在我們的服務器的代碼中,首先,就是建立一個端口好爲8888的Tcp通道,數據使用二進制方式傳輸,這樣,服務器端將在端口8888進行監聽。然後ChannelServices::RegisterChannel註冊Tcp通道和服務。RemotingConfiguration::RegisterWellKnownServiceType把需要被遠程訪問的對象註冊爲已知類型。第一個參數,爲對象的類型,第二個參數,是一個字符串,它和遠程客戶端訪問的時候,用的URI有關。舉個例子,在我們的程序中,本機調試的情況下,客戶端訪問客戶端的遠程對象的時候URI的地址就爲: tcp://localhost:8888/Test ,localhost是指向本機的,如果在內部網絡中,可以指定爲服務器端的IP地址。 第三個參數,是調用的方式,在Remoting中,分爲Singleton和SingleCall。二者的差別,我在以後的文章中會介紹。SingleCall,會在客戶端每次訪問的時候,創建一個實例,而Singleton只是創建一個實例,以後客戶端的調用,都是共享這個實例。

實現遠程客戶端:
#include "stdafx.h"
#using 

using namespace System;
using namespace System::Runtime::Remoting;
using namespace System::Runtime::Remoting::Channels;
using namespace System::Runtime::Remoting::Channels::Tcp;

using namespace RemoteObject;

int _tmain()
{
TcpClientChannel *Channel=new TcpClientChannel();
ChannelServices::RegisterChannel(Channel);

RemoteObjClass *pObj=static_cast(
Activator::GetObject(
Type::GetType("RemoteObject.RemoteObjClass,RemoteObject"),
S"tcp://localhost:8888/Test"));

Console::WriteLine(S"Return String is:{0}",pObj->DisplayMessage());
Console::ReadLine();
return 0;

  在我們建立了服務端和遠程對象之後,客戶端就比較簡單了。主要就是創建一個TcpChannel對象,用於和服務器端通信,不同的地方,是我們不需要指定一個端口。因爲在客戶端可以使用任何一個隨機的端口。Activator::GetObject用來獲取對遠程對象的引用。之後,我們就可以像調用本地對象一樣,來調用遠程對象的方法了。程序的運行結果如下圖:

  整個過程就是這樣了。和DCOM相比較,我們會看到,Remoting比DCOM簡化了很多。在以後的文章,我會詳細介紹Remoting的其他功能和特性。 以上程序,需要.NET Framework 1.1的支持。  
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章