.NET Remoting编程简介

转载 2007年09月21日 16:37:00
.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名字空间结束

<
BR>编译创建的工程,就会得到一个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使用起来很简单,而且为处理局域网甚至互联网范围内的资源提供了一个绝佳的方法。  

.NET Remoting服务器端订阅客户端事件

模拟情景:在天龙八部中,有信使通知住持,说,带头大哥说契丹人要来抢经书了。客户端订阅服务器端事件,于是向服务器端发送消息。 1.服务器端代码,设计服务器端要提供的服务 namespace Remo...
  • yoyoshaoye
  • yoyoshaoye
  • 2012年01月07日 22:06
  • 1589

.NET Remoting编程简介

 .NET Remoting提供了一个功能强大、高效的处理远程对象的方法,从结构上而言,.NET Remote对象非常适合通过网络访问资源,而又无需处理由基于SOAP的WebServices所带来的难...
  • ChampaignWolf
  • ChampaignWolf
  • 2007年04月05日 17:42
  • 671

.NET Remoting编程简介

 NET Remoting提供了一个功能强大、高效的处理远程对象的方法,从结构上而言,.NET Remote对象非常适合通过网络访问资源,而又无需处理由基于SOAP的WebServices所带来的难题...
  • appoFeng
  • appoFeng
  • 2008年02月01日 10:27
  • 413

.NET Remoting编程简介

NET Remoting提供了一个功能强大、高效的处理远程对象的方法,从结构上而言,.NET Remote对象非常适合通过网络访问资源,而又无需处理由基于SOAP的WebServices所带来的难题。...
  • lanwilliam
  • lanwilliam
  • 2008年05月23日 09:01
  • 443

.net Remoting用TCP和HTTP区别(上)

2010年04月04日 星期日 11:08Remoting和WebService都是.Net提供的远程访问的方法,Remoting具有以下几个优点 1、Tcp通道的Remoting速度非常快 2、...
  • flywkk1218
  • flywkk1218
  • 2010年12月29日 14:58
  • 1486

简述WebService与.NET Remoting的区别及适应场合

为了能清楚地描述Web Service 和Remoting之间的区别,我打算从他们的体系结构上来说起: Web Service大体上分为5个层次: 1. Http传输信道 2. XML的数据格式 3....
  • zhoufoxcn
  • zhoufoxcn
  • 2007年06月12日 23:38
  • 4419

.NET Remoting 最简单示例

学习技术知识一个好的方法是先动手,再深入, 给出一个最简单的Remoting程序示例(C#)如下: Step1:创建类库(DLL)工程RemotingObjects,类Person代码如下: us...
  • kissqw
  • kissqw
  • 2014年01月21日 15:29
  • 20412

.Net中Remoting通信机制

Remoting通信机制 Remoting介绍 主要元素 通道类型 激活方式 对象定义 Remoting介绍 什么是Remoting,简而言之,我们可...
  • CoderJYF
  • CoderJYF
  • 2016年12月06日 17:25
  • 1535

.net Remoting的工作原理

     .NET Remoting 提供了一种允许对象通过应用程序域与另一对象进行交互的框架。在Remoting中是通过通道(channel)来实现两个应用程序域之间对象的通信的。      首先,...
  • hawking3000
  • hawking3000
  • 2010年06月15日 23:55
  • 3848

[原创].NET Remoting: 如何通过Remoting实现双向通信(Bidirectional Communication)

Remoting是NET平台下比较成熟高效的分布式技术,我们习惯采用传统的远程调用的方式使用Remoting。在客户端所在的Application Domain,我们通过Proxy(Transp...
  • artech
  • artech
  • 2007年03月01日 19:32
  • 993
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:.NET Remoting编程简介
举报原因:
原因补充:

(最多只允许输入30个字)