.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-Resume
  ResumeID, numeric (autonumber)
  UserID, numeric
  Title, Char(30)
  Body, Text

双击我们在第二步中创建的Server.exe,然后双击在第三步中创建的Client可执行文件。如果一切正常的话,我们应该能够看到数据库中ResumeID的值为1的记录行。

总之,.NET Remoting使用起来很简单,而且为处理局域网甚至互联网范围内的资源提供了一个绝佳的方法。

时间: 2024-10-26 14:12:38

.NET Remoting编程简介的相关文章

.NET Remoting编程简介(转)

.NET Remoting编程简介 (刘彦青编译 2001年11月02日 09:25) .NET Remoting提供了一个功能强大.高效的处理远程对象的方法,从结构上而言,.NET Remote对象非常适合通过网络访问资源,而又无需处理由基于SOAP的WebServices所带来的难题..NET Remoting使用起来比Java的RMI简单,但要比创建Web Service难度大一些.广告

使用Agavi进行MVC编程简介,第5部分

使用Agavi进行MVC编程简介,第5部分:为Agavi应用程序添加分页.上传文件和定制输入验证器 简介 在本系列的第 4 部分结束之后,您已经具备一个功能齐全的 Web 应用程序,该应用程序包含管理模块.搜索引擎和 XML 输出功能.现在,您可能对本文讨论的主题摸不着头脑,因为 Web Automobiles Sales Platform (WASP) 应用程序的基本需求已经得到满足. 在最后一篇文章中,我将讨论一些您在构建 Web 应用程序时必须使用的额外技术和概念.这些技术覆盖较大的范围,

使用Agavi进行MVC编程简介,第4部分

使用Agavi进行MVC编程简介,第4部分: 创建一个带有多种输出类型(XML.RSS 或SOAP)的Agavi搜索引擎 简介 在本系列的第 3 部分中,您经历了构建基于 Web 的应用程序时经常遇到的一个任务:实现一个允许管理员通过 Web 界面执行 CRUD 操作的管理模块.您还探索了 Agavi 的安全模型,构建了用于验证用户的登录系统,以保护对应用程序资源的访问. 现在继续 Agavi 学习,为这个 WASP(Web 汽车销售平台)示例应用程序添加更多功能.您将实现一个搜索引擎,允许用户

使用Agavi进行MVC编程简介,第2部分 (二)

使用Agavi进行MVC编程简介,第2部分:使用Agavi和Doctrine添加表单和数据库支持2 获取数据库记录 现在,Agavi.Doctrine和MySQL之间的通信已经畅通,接下来需要编写一个ViewAction,以从MySQL数据库获取并显示汽车列表.首先,使用一些示例记录填充 listing 表:这方便您在操作的初始开发阶段对其进行测试: mysql> INSERT INTO listing (RecordID, RecordDate, OwnerName, OwnerTel, Ow

使用Agavi进行MVC编程简介,第2部分 (一)

使用Agavi 进行MVC编程简介,第2部分: 使用Agavi和Doctrine添加表单和数据库支持1 简介 在本系列的第 1 部分中,我介绍了Agavi并解释了一些特性,这些特性让 Agavi 适合用于构建可扩展.遵从标准的Web应用程序.通过使用样例应用程序 Web Automobiles Sales Platform (WASP),我逐步向您展示了创建新的Agavi 项目的基础知识,帮助您理解 Agavi 推荐的文件系统布局,并熟悉 Agavi 的命令行构建脚本.我还介绍了所有 Agavi

[Qt教程] 第31篇 网络(一)Qt网络编程简介

[Qt教程] 第31篇 网络(一)Qt网络编程简介 楼主  发表于 2013-8-28 17:04:17 | 查看: 515| 回复: 0 Qt网络编程简介 版权声明 该文章原创于作者yafeilinux,转载请注明出处! 导语 从这一节开始我们讲述Qt网络应用方面的编程知识.在开始这部分知识的学习之前,大家最好已经拥有了一定的网络知识和Qt的编程基础.在后面的教程中我们不会对一个常用的网络名词进行详细的解释,对于不太了解的地方,大家可以参考相关书籍. 不过,大家也没有必要非得先去学习网络专业知

《JavaScript和jQuery实战手册(原书第3版)》---第1章 编写第一个JavaScript程序 1.1 编程简介

本节书摘来自华章出版社<JavaScript和jQuery实战手册(原书第3版)>一书中的第1章,第1.1节,作者David Sawyer McFarland,姚待艳 李占宣 译,更多章节内容可以访问"华章计算机"公众号查看. 第1章 编写第一个JavaScript程序 HTML自身并没有太多智能:它不能做数学运算,不能判断某人是否正确填写了一个表单,而且不能根据Web访问者的交互来做出判断.基本上,HTML让人们阅读文本.观看图片或视频,并且单击链接转向拥有更多文本.图片

套接字编程简介

套接字编程简介 项目:UNIX网络编程学习 作者:曾金龙 供职:(深圳迅雷网络技术股份有限公司) 领域:迅雷下载库研发 日期:2014-07-25 1, TCP连接图 socket编程,过眼烟云的去看,无外乎就那么几个API,但是,如果想登堂入室,必须注重里面的每一个细节. 对于TCP编程而言,最重要的是记住这么一幅图.死记的基础上理解. windows下有visio,ubuntu下只好用Dia,不是很习惯,而且不支持中文输入. 图1 TCP连接的数据包交换图 你特别需要注意的是: 1)哪个地方

《面向对象设计实践指南:Ruby语言描述》—第1章 1.4节 面向对象编程简介

1.4 面向对象编程简介 面向对象设计实践指南:Ruby语言描述 面向对象的应用程序由对象和它们之间传递的消息构成.其中,消息相对更为重要.但在本节的简介里(以及在本书的前面几个章节里),这两个概念都同等重要. 1.4.1 过程式语言 相对于非面向对象(或过程式)的编程来说,面向对象编程是面向对象的.依据这两种风格的差异来考虑它们很有意义.假设有这么一种通用的编程语言,它可用来创建简单的脚本.在这门语言里,你可以定义变量(即组成多个名称),并将这些名字与少量的数据相关联.一旦进行了分配,便可以通