初识用.NET Remoting来开发分布式应用

一..NET Remoting简介:

.NET Remoting从某种意义上讲是DCOM的替代品。ASP.NET Web服务十分有用,但是这项技术在企业内联网的解决方案中,对于某些业务请求来说并不快,也没有足够的灵活性,而且,ASP.NET Web服务需要有运行时的支持。使用.NET Remoting技术后,可以将Web服务提供给世界上的任何地方。而且可以在所有的应用程序类型中运行Web服务。

二..NET Remoting 的基本原理:

体系结构图如下:

 

三.几个重要的概念:

1.远程对象:

远程对象类是从MarshalByRefObject类中派生的。跨越应用程序域调用这个类需要使用代理。.NET Remoting支持两种类型的远程对象:知名的(Well-known)远程对象和客户激活(Client-activated)远程对象。远程对象其实包括两层含义:

操作远程对象:对象运行在远程,客户段向他发送消息;

传递远程对象:将远程对象拿到本地,或者将本地对象发送过去,对副本进行操作。

2.激活:

使用new运算符可以激活远程对象。还有其它一些方式也可以激活远程对象,在以后的随笔里面我会介绍。

3.通道:

一个远程对象使用通道发送和接收消息。服务器选择一个通道来监听请求,客户端选择通道来和服务器通讯。Remoting提供了内置的通道:TCP通道和HTTP通道,我们也可以编写自己的通道。

4.编组:

数组通过应用程序域被传递的过程称为编组。将变量作为远程对象的参数来发送时,这个变量必须被转换,以便能够通过应用程序域发送该变量。

5.监听:

使用监听,能够将某些功能置入到方法调用链中。如果调用某个对象的方法,监听层便能够捕获调用来转换方法调用,或是完成某些日志记录。.NET Remoting调用链的每一部分都是用监听。

四.开发Remoting三步走:

开发.NET Remoting分三步走,在这里以一个简单的例子来说明。

1.创建远程对象:

继承System.MarshalByRefObject

 1using System;
 2using System.Collections;
 3using System.Text;
 4
 5namespace SimpleRemoting
 6{
 7    public class HelloServer : MarshalByRefObject
 8    {
 9        public HelloServer()
10        {
11            ///输出信息,服务器激活
12            Console.WriteLine("服务器激活……");
13        }

14        public String HelloMethod(String name)
15        {
16            Console.WriteLine(
17                "服务器端 : {0}", name);
18            return "这里是:" + name;
19        }

20    }

21}


2.创建宿主应用程序:

注册通道

注册服务器激活的远程对象

运行宿主程序

 1using System;
 2using System.Net;
 3using System.Runtime.Remoting;
 4using System.Runtime.Remoting.Channels;
 5using System.Runtime.Remoting.Channels.Tcp;
 6using System.Runtime.Remoting.Channels.Http;
 7
 8namespace SimpleRemoting 
 9{
10
11    public class Server
12    {
13        public static int Main(string [] args) 
14        {
15            
16            ///创建Tcp通道
17            TcpChannel chan1 = new TcpChannel(8085);
18
19            ///创建Http通道
20            HttpChannel chan2 = new HttpChannel(8086);
21            
22            ///注册通道
23            ChannelServices.RegisterChannel(chan1);
24            ChannelServices.RegisterChannel(chan2);
25
26            RemotingConfiguration.RegisterWellKnownServiceType
27                (
28                typeof(HelloServer),
29                "SayHello",
30                WellKnownObjectMode.Singleton
31                );
32            
33
34            System.Console.WriteLine("按任意键退出!");
35            ///下面这行不能少
36            System.Console.ReadLine();
37            return 0;
38        }

39
40    }

41}

42
43


3.建立客户端程序:

注册通道

根据URL得到对象代理

使用代理调用远程对象

 1using System;
 2using System.Runtime.Remoting;
 3using System.Runtime.Remoting.Channels;
 4using System.Runtime.Remoting.Channels.Tcp;
 5using System.Runtime.Remoting.Channels.Http;
 6using System.IO;
 7
 8namespace SimpleRemoting 
 9{
10    public class Client
11    {
12        public static void Main(string[] args)
13        {
14            ///使用TCP通道得到远程对象
15            TcpChannel chan1 = new TcpChannel();
16            ChannelServices.RegisterChannel(chan1);
17
18            HelloServer obj1 = (HelloServer)Activator.GetObject(
19                typeof(SimpleRemoting.HelloServer),
20                "tcp://localhost:8085/SayHello");
21
22            if (obj1 == null)
23            {
24                System.Console.WriteLine(
25                    "连接TCP服务器失败");
26            }

27
28            ///使用HTTP通道得到远程对象
29            HttpChannel chan2 = new HttpChannel();
30            ChannelServices.RegisterChannel(chan2);
31
32            HelloServer obj2 = (HelloServer)Activator.GetObject(
33                typeof(SimpleRemoting.HelloServer),
34                "http://localhost:8086/SayHello");
35
36            if (obj2 == null)
37            {
38                System.Console.WriteLine(
39                    "连接HTTP服务器失败");
40            }

41            
42            ///输出信息
43            Console.WriteLine(
44                "ClientTCP HelloMethod {0}",
45                obj1.HelloMethod("Caveman1"));
46            Console.WriteLine(
47                "ClientHTTP HelloMethod {0}",
48                obj2.HelloMethod("Caveman2"));
49            Console.ReadLine();
50        }

51    }

52}

53


结束语:初识用.NET Remoting来开发分布式应用就到这里了,有时间我会就.NET Remoting技术写成系列文章。包括基于租约的生存期,编组,异步远程调用等等。

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2005-11-03 08:34 TerryLee 阅读(3320) 评论(27)  编辑 收藏 网摘 所属分类: [04]  WCF后传

  回复  引用  查看    
#1楼 2005-11-03 08:48 | navyliu      
不错,收藏起来,有空学习!
  回复  引用  查看    
#2楼 [楼主]2005-11-03 08:59 | Terrylee      
@navyliu
^_^
  回复  引用  查看    
#3楼 2005-11-03 14:39 | Jason.NET      
收下了,3q
  回复  引用  查看    
#4楼 2005-11-03 14:43 | NeedForSleep      
好东西。。。。。
  回复  引用  查看    
#5楼 [楼主]2005-11-03 15:27 | Terrylee      
@Jason.NET ,NeedForSleep
多谢支持:)
  回复  引用  查看    
#6楼 2005-11-03 18:23 | Dragonpro      
不错
  回复  引用  查看    
#7楼 2005-11-04 09:16 | oo复oo      
是不是搞反了? 只有Web Services才是不需要.net运行时的,在世界上通用,是开放的,.net可以与java 或任何语言创建的Web Services 通讯,反之也行。

而.net Remoting在通讯的两端都需要 .net 运行时。 当然,我没有仔细研究,希望是我错了。
  回复  引用  查看    
#8楼 2005-11-04 09:41 | jhtchina      
学习, 收藏
  回复  引用    
#9楼 2005-11-04 09:47 | microhf [未注册用户]
只有Web Services才是不需要.net运行时的,在世界上通用,是开放的,.net可以与java 或任何语言创建的Web Services 通讯,反之也行。

而.net Remoting在通讯的两端都需要 .net 运行时。

肯定是这样的!
  回复  引用  查看    
#10楼 2005-11-04 10:31 | Baige      
最好能将建立服务器端的发布代码和客户端接收对象的代码做一个封装
用起来就很方便了~
  回复  引用  查看    
#12楼 [楼主]2005-11-07 09:06 | Terrylee      
@旻

多谢多谢!

其实我不能算是一个Remoting的爱好者,只是偶尔看看这方面的书:)

  回复  引用  查看    
#13楼 2005-11-28 10:13 | Neil      
有一点不是很明白,客户端调用服务器远程对象的时候,HelloServer类不是服务器端的吗?客户端怎么能用,是定义相同的接口调用吗?
  回复  引用  查看    
#14楼 [楼主]2005-11-28 10:42 | Terrylee      
@Neil

在实际运用中,客户端通过创建HelloServer类的代理来实现,这里为了讲解简单,没有去写。

代理类不需要手工去写,可以通过工具生成。
  回复  引用  查看    
#15楼 2005-11-28 16:12 | Neil      
谢谢你的介绍,对我了解remoting帮助很大。^^
  回复  引用  查看    
#16楼 [楼主]2005-11-28 16:26 | Terrylee      
@Neil

呵呵,大家互相交流嘛

有时间我会尽我自己所学的写一个完整的Remoting的例子,供大家参考:)
  回复  引用    
#17楼 2005-12-31 13:35 | 同意 [未注册用户]
的确,web service更加通用一些,跨平台,互操作都是remoting不能比拟的。微软有一个专门的地方,你可以把你自己建立的web service上传到那里,供全世界的人使用。remoting的客户端需要.net framework
  回复  引用  查看    
#18楼 [楼主]2005-12-31 14:15 | Terrylee      

@同意

你说的应该是http://uddi.microsoft.com/

Remoting在局域网内也有着它的优势
 

  回复  引用    
#19楼 2006-01-01 02:19 | nick12345 [未注册用户]
而且,ASP.NET Web服务需要有运行时的支持。使用.NET Remoting技术后,可以将Web服务提供给世界上的任何地方。而且可以在所有的应用程序类型中运行Web服务。

这句话不敢苟同.....
  回复  引用  查看    
#20楼 [楼主]2006-01-03 12:27 | Terrylee      
@12345

这句话有些问题

一直没有来得及更正

在这里向大家道歉:)

————————————————————————————————————————
“ASP.NET Web服务需要有运行时的支持。使用.NET Remoting技术后,可以将Web服务提供给世界上的任何地方。而且可以在所有的应用程序类型中运行Web服务。 ”

我是初学者,但是想看看关于remoting和web service方面的东西!谢谢阿!要是再来个web service方面的例子就更好了!呵呵。我的qq:86562467,希望可以互相学习交流啊!
  回复  引用  查看    
#22楼 [楼主]2006-02-15 08:19 | Terrylee      
@大鹏展翅 QQ:86562467

Web Service的例子网上应该有很多:)
  回复  引用  查看    
#23楼 2006-06-27 14:12 | superstar      
图画得不错
  回复  引用    
#24楼 2007-04-23 17:15 | 私家侦探 [未注册用户]
HelloServer obj1 = (HelloServer)Activator.GetObject(
typeof(SimpleRemoting.HelloServer),
"tcp://localhost:8085/SayHello");
----------------------------
上面的意思是获得远程对象,可是很纳闷??
1.获得的远程对象不是有状态的对象,初始化一个对象不稀奇,把一个已经存在各种数据的类读过来才稀奇

2,客户端中既然有上面的代码,就说明客户端要引用那个远程类,那倒不如
在客户端直接HelloServer obj1=new HelloServer();更快一点。

3,现在一个网站经常是多域名,如果remoting能够解决多域名下会话变量共享,就真是一种好的技术,典型的例子是在一个域名下登陆后访问另一个域名无需再登陆,比如在csdn的论坛中登陆后,再去访问csdn首页,应该提示欢迎某某人,也就是做到会话多域名下共享。现在用cookies可以间接做到会话变量的传递。

探讨探讨呵呵remoting我也不会

  回复  引用  查看    
#25楼 2008-01-29 14:37 | webBoy(涂鸦中...)      
很清晰,不过不具体
  回复  引用    
#26楼 2008-07-19 11:16 | badgirl [未注册用户]
这个似乎是仁旻写的代码吧,楼主盗用了他的,还是他盗用了楼主的?
  回复  引用  查看    
#27楼 2008-09-27 23:41 | 大李      
由于目标机器积极拒绝,无法连接。 127.0.0.1:8085

对着视频和lz的代码,也没搞明白什么事情
是机器防火墙等其他问题呢,还是代码有问题呢
3个工程,一个类,两个控制台。client执行,
错在哪呢?




标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2006-11-26 13:18 编辑过
Google站内搜索

相关文章:

相关链接: