.NET Remoting編程簡介

.NET Remoting提供了一個功能強大、高效的處理遠程對象的方法,從結構上而言,.NET Remote對象非常適合通過網絡訪問資源,而又無需處理由基於SOAP的WebServices所帶來的難題。.NET Remoting使用起來比Java的RMI簡單,但要比創建Web Service難度大一些。

在本篇文章中,我們將創建一個從數據庫讀入內容的遠程對象。文中還包括了一個忽略數據庫功能的替補對象,以使沒有數據庫可以使用的讀者仍然能夠使用.NET Remoting。
第一步:創建共享庫依次點擊“文件”-“新創建”-“工程”,選擇創建一個C# Library,並將其命名爲ResumeServerLibrary,然後點擊OK按鈕。這將創建一個我們的.NET Remote客戶端和服務器端用來通訊的“共享命令集”。
正面是完整的代碼,如果要跳過數據庫訪問部分,可以使用下面的代碼替換ResumeLoader對象:

public class ResumeLoader :
 System.MarshalByRefObject{
  public ResumeLoader(){
   System.Console.WriteLine("New Referance Added!");
  }
  public Resume GetResumeByUserID(decimal userID){
   return new Resume(1);
  }
 }
 
名字空間是對象所需要的。請記住,如果得到System.Runtime.Remoting.Channels.Tcp名字空間不存在的信息,請檢查是否象上面的代碼那樣添加了對System.Runtime.Remoting.dll的引用。
using System;using System.Runtime;using System.Data.SqlClient;
我們爲對象使用的名字空間是DotNetRemoteTest,下面的對象是MarshalByRefObject,在其中我們創建了一個引用和包括服務器端數據庫操作全部完成所需要的所有工作。
namespace DotNetRemoteTest{
public class ResumeLoader : System.MarshalByRefObject{private SqlConnection dbConnection;
public ResumeLoader(){this.dbConnection = new System.Data.SqlClient.SqlConnection();this.dbConnection.ConnectionString ="data source=GRIMSAADO2K;initial catalog=underground;integrated security=SSPI;pers" +"ist security info=True;workstation id=GRIMSAADO2K;packet size=4096";/*具體的連接字符串會有所不同,這超出了本篇文章的範圍。如果不清楚如何創建一個數據庫連接,請使用這一對象的另一個版本。*/System.Console.WriteLine("New Referance Added!");}
public Resume GetResumeByUserID(decimal userID){Resume resume = new Resume();try{dbConnection.Open();SqlCommand cmd = new SqlCommand("SELECT ResumeID, UserID, Title, Body FROM Resume as theResume WHERE theResume.UserID="+ userID +"", dbConnection);SqlDataReader aReader = cmd.ExecuteReader();if(aReader.Read()){resume.ResumeID=aReader.GetDecimal(0);resume.UserID=aReader.GetDecimal(1);resume.Title=aReader.GetString(2);resume.Body=aReader.GetString(3);}aReader.Close();dbConnection.Close();}catch(Exception x) { resume.Title="Error:"+x; }return resume;}}
 
Resume需要能夠被串行化,以便能作爲被遠程調用的.NET Remote對象的返回類型,原因是該對象將被轉換爲通過網絡傳輸的原始數據,然後在網絡的另一端再被裝配成一個對象。
該對象非常簡單,爲了使本篇文章看起來更簡單,其中的構造器甚至使用缺省的內容初始化其中的一些域。
[Serializable]public class Resume{private decimal resumeID, userID;private String body, title;
public Resume(decimal resumeID){this.ResumeID=resumeID;this.UserID=1;this.Body="This is the default body of the resume";this.Title="This is the default Title";}
public decimal ResumeID{get { return resumeID; }set { this.resumeID=value; }}public decimal UserID{get { return userID; }set { this.userID=value; }}public String Body{get { return body; }set{this.body=value;}}public String Title{get { return title; }set{ this.title=value; }}
}//RESUME對象結束
}//DotNetRemoteTest名字空間結束
 
編譯創建的工程,就會得到一個DLL文件,並可以在其他的工程中使用它。
第二步:創建Server對象有幾種方法可以創建Server對象,最直觀的方法是下面的方法:在Visual Studio.NET中,依次點擊“文件”-“新創建”-“工程”,選擇創建一個“Command Line Application”(命令行應用程序),並將它命名爲ResumeSuperServer。
最最重要的是,我們需要添加對剛纔在第一步中所創建的DLL文件的應用,該應用程序才能正確地運行。依次點擊“工程”-“添加引用”,然後通過點擊“瀏覽”按鈕添加一個對在第一步中所創建的DLL文件的引用。
爲了使用.NET remote功能,必須通過選擇“工程”-“添加引用”,添加對DLL文件的引用。在.NET標籤中選擇System.Runtime.Remoting.DLL,然後點擊“OK”按鈕。然後,需要象我們在第一步中那樣添加對System.Runtime.Remoting.dll的引用。
下面的對象相當的簡單和直觀,我將就真正與.NET remoting相關的3行代碼中的每一行進行解釋。
TcpServerChannel是.NET remoting支持的二種信道類型中的一種,它將設置我們希望我們的對象對來自哪一個端口的請求進行迴應,ChannelServices.RegisterChannel將把該端口號與操作系統中的TCP/IP棧綁定。
TcpServerChannel channel = new TcpServerChannel(9932);ChannelServices.RegisterChannel(channel);
另一種可以設置的信道類型是HTTP,只要簡單地使用System.Runtime.Remoting.Channels.Http名字空間中的HttpServerChannel對象即可搞定。使用HTTP和TCP信道之間的區別可以簡單的歸結爲:如果應用程序是在局域網上運行,則最好使用TCP信道,因爲它的性能要好於HTTP信道;如果應用程序是在互聯網上運行,則有時候根據防火牆的配置,HTTP是唯一的選擇。需要記住的是,如果使用了防火牆軟件,則防火牆應該配置成允許TCP數據流量通過你爲對象選擇的端口。
RemotingConfiguration.RegisterWellKnownServiceType(typeof(ResumeLoader), "ResumeLoader", WellKnownObjectMode.SingleCall);
這行代碼設置了服務中的一些參數和把欲使用的對象名字與遠程對象進行綁定,第一個參數是綁定的對象,第二個參數是TCP或HTTP信道中遠程對象名字的字符串,第三個參數讓容器知道,當有對對象的請求傳來時,應該如何處理對象。儘管WellKnownObjectMode.Single對所有的調用者使用一個對象的實例,但它爲每個客戶生成這個對象的一個實例。
完整的對象代碼如下所示:
using System;using System.Runtime;using System.Runtime.Remoting;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting.Channels.Tcp;using System.Data.SqlClient;using DotNetRemoteTest;
namespace ResumeServerServer{public class ResumeSuperServer{public static void Main(String[] args){TcpServerChannel channel = new TcpServerChannel(9932);ChannelServices.RegisterChannel(channel);RemotingConfiguration.RegisterWellKnownServiceType(typeof(ResumeLoader),"ResumeLoader", WellKnownObjectMode.SingleCall);System.Console.WriteLine("Press Any Key");System.Console.ReadLine();}}}
 
編譯這一程序並注意生成的.EXE文件的位置。
第三步:創建Remote客戶端程序ResumeClinet是我們爲對在上面創建的ResumeSuperServer遠和對象進行測試而創建的。要創建這一工程,可以依次點擊“文件”-“創建”-“工程”,然後選擇創建一個Console Application類型、名字爲ResumeClient的工程名。象在第二步中那樣,我們需要添加對在第一步中創建的DLL文件和System.Runtime.Remoting DLL的引用。
下面的代碼中有二行對於.NET remoting而言是特別重要的。第一行創建了一個TCP客戶端信道,該信道並不是綁定在一個端口上的;第二行獲取了一個對遠程的ResumeLoader對象的引用。Activator.GetObject方法返回一個對象類型的值,我們隨後會將它返回的值賦予ResumeLoader。我們傳給它的參數與在服務器工程中傳遞給RemotingConfiguration的參數非常地相似,第一個參數是對象類型的,第二個參數是遠程對象的URI。
ChannelServices.RegisterChannel(new TcpClientChannel());ResumeLoader loader = (ResumeLoader)Activator.GetObject(typeof(ResumeLoader), "tcp://localhost:9932/ResumeLoader");
ResumeClient的全部代碼如下所示:using System;using System.Runtime.Remoting;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting.Channels.Tcp;using DotNetRemoteTest;
namespace ResumeClient{
public class ResumeClient{
public static void Main(string[] args){ChannelServices.RegisterChannel(new TcpClientChannel());ResumeLoader loader = (ResumeLoader)Activator.GetObject(typeof(ResumeServer), "tcp://localhost:9932/ResumeLoader");
if(rs==null){ Console.WriteLine("Unable to get remote referance"); }else{Resume resume = loader.GetResumeByUserID(1);Console.WriteLine("ResumeID:"+ resume.ResumeID);Console.WriteLine("UserID:"+ resume.UserID);Console.WriteLine("Title:"+ resume.Title);Console.WriteLine("Body:"+ resume.Body);}Console.ReadLine();//在能夠看到結果前不讓窗口關閉}//END OF MAIN METHOD}//END OF ResumeClient Object}//END OF ResumeClientNamespace
 
測試在數據庫中創建一個具有如下結構的表:
Table Name-ResumeResumeID, numeric (autonumber)UserID, numericTitle, Char(30)Body, Text
雙擊我們在第二步中創建的Server.exe,然後雙擊在第三步中創建的Client可執行文件。如果一切正常的話,我們應該能夠看到數據庫中ResumeID的值爲1的記錄行。
總之,.NET Remoting使用起來很簡單,而且爲處理局域網甚至互聯網範圍內的資源提供了一個絕佳的方法。  

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