.NET Remoting編程簡介

來源:互聯網
上載者:User
編程 .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-Resume
  ResumeID, numeric (autonumber)
  UserID, numeric
  Title, Char(30)
  Body, Text

雙擊我們在第二步中建立的Server.exe,然後雙擊在第三步中建立的Client可執行檔。如果一切正常的話,我們應該能夠看到資料庫中ResumeID的值為1的記錄行。

總之,.NET Remoting使用起來很簡單,而且為處理區域網路甚至互連網範圍內的資源提供了一個絕佳的方法。






相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。