Remoting基本概念&牛刀小试

Remoting技术简介

一 Remoting技术出现的背景

1)分布式应用需求的迅速增长(Peer-to-Peer, Grid等技术的出现)
2)原有的C/S, B/S模式和技术已经不能胜任(串口RS232,Socket,RPC,DCOM技术各有缺点)


二 什么是Romoting?

采用分布式进行编程的一种技术,Remoting主要用于管理跨应用程序域的同步和异步RPC 会话。在默认情况下,Remoting使用 HTTP 或 TCP 协议,并使用 XML 编码的 SOAP 或本机二进制消息格式进行通信。.NET Remoting 提供了非常灵活和可扩展的编程框架,并且他可以管理对象的状态。

Remoting优点:
1)  性能: 如果调优.Net Remoting 的性能,那么他的性能非常好,速度接近DCOM.
2) 可扩展:.Net Remoting 可供你选择传输通道类型(如Http,Tcp)和格式类型(如Binary,Soap)。
3) 可配置:可以通过配置文件配置应用程序。
4) CLR和CTS的好处:由于.NET Remoting是基于.NET框架的,所以他拥有Common Type System(CTS) 和 Common Language Runtime(CLR)所拥有的易于使用和功能强大的特点。
5)互用性(Interoperability): .NET Remoting 支持开发标准(Http,SOAP,WSDL,XML).
6) 安全性
7) 生命周期管理


三 Remoting架构:

 Remoting通过通道(channel)来传输消息。.NET Remoting支持两种默认的协议支持通道(Http和Tcp).

RemotiStructure.gif


四 远程对象的两个含义

操作远程对象:对象运行在远程,客户端向他发送消息.
传递远程对象:将远程的对象拿到本地,或者将本地对象发送过去,然后我们可以对副本进行操作.


五 激活对象的两种方式:
服务器激活和客户端激活

1 服务器激活:
“服务器激活的对象”是由服务器控制生存期的对象。它们只在客户端调用对象的第一个方法时,根据需要由服务器创建。服务器激活的对象只支持默认的构造函数。
代码:
2) SingleCall(单调用)
SingleCall 远程服务器类型总是为每个客户端请求设置一个实例。下一个方法调用将改由其他实例进行服务。从设计角度看,SingleCall 类型提供的功能非常简单。这种机制不提供状态管理,如果您需要状态管理,这将是一个不利之处;如果您不需要,这种机制将非常理想。也许您只关心负载平衡和可伸缩性而不关心状态,那么在这种情况下,这种模式将是您理想的选择,因为对于每个请求都只有一个实例。如果愿意,开发人员可以向 SingleCall 对象提供自己的状态管理,但这种状态数据不会驻留在对象中,因为每次调用新的方法时都将实例化一个新的对象标识。
特点:
a.每次调用都实例化新的实例
b.更好地支持无状态编程模型

2 客户端激活
“客户端激活的对象”是当客户端调用 newActivator.CreateInstance() 时在服务器上创建的。
代码:

None.gif < service >
None.gif  
< wellknown  mode ="SingleCall"  type ="Hello.HelloService, Hello"  
None.gif                   objectUri
="HelloService.soap"   />
None.gif
</ service >
None.gif

上面描述了一个服务器激活的 (wellknown) 类型,其激活方式设置为 SingleCall

服务器激活的对象有两种激活模式:SingletonSingleCall.
1) Singleton(单实例):
这些对象遵循传统的Singleton 设计模式,在这种模式中,任何时候内存中都只有一个实例,所有客户端都接受该实例提供的服务。
特点:
a.在服务器段只实例化一次,以后每次调用都访问同一个实例。
b.可以维持状态

None.gif < service >
None.gif  
< activated  type ="Hello.HelloService, Hello"  
None.gif             objectUri
="HelloService.soap"   />
None.gif
</ service >
None.gif

上面描述了一个客户端激活的类型。请注意,我们不再需要 URL,因为对于客户端激活的类型,类型本身就足以激活了。另外,wellknown 标记已被 activated 标记替代。

六 Remoting VS Web Service

这两者都是基于分布式的开发,而且.Net Remoting有时也可以配置为Web Service,两者有很多的相同之处。

一般来讲,我把他们的不同之处列为5个方面。

1) 开发部署
 WebService开发和部署比较简单,Remoting相对WebService开发和部署要稍复杂。
2) 协议的开放性 
    两者都可支持HTTP,TCP,SMTP等多种协议。
    [一直以为WebService只支持HTTP协议,经idior指点,原来在Web Services Enhancements已有介绍,WebService也支持TCP,SMTP等协议。微软最新发布的wse应该是wse 3.0,以前还没听说过,真是汗颜!]
   更详细的内容待续...
3) 支持的类型系统
 WebService只支持XSD类型系统,对象的类型的序列化受到限制,而Remoting可以通过序列化为Binary传输数据,支持更为广泛的数据类型
4) 安全性
 
由于 ASP.NET Web 服务依赖于 HTTP,因此它们与标准的 Internet 安全性基础结构相集成。ASP.NET 利用 IIS 的安全性功能,为标准 HTTP 验证方案(包括基本、简要、数字证书,甚至 Microsoft .NET Passport)提供了强有力的支持。
 一般情况下,.NET Remoting 管线不能确保跨进程调用的安全。使用 ASP.NET 托管于 IIS 中的 .NET Remoting 端点可以利用 ASP.NET Web 服务可用的所有安全性功能,包括对使用 SSL 确保有线通信的安全性的支持。
5) 性能
从原始性能方面来讲,使用 TCP 信道和二进制格式化程序时,.NET Remoting 管线能够提供最快的通信。一般情况下,.NET Remoting的性能要比WebService高。

 

下面的Remoting程序,采用了Singleton模式的服务器端激活的方式,分为三部分。
General:一个远程对象公用的程序集。
Server:服务器端
Client:客户端


一 创建第一个Remoting控制台程序

在创建程序之前,先把几个要用到的类先介绍一下:

1) MarshalByRefObject类:

允许在支持远程处理的应用程序中跨应用程序域边界访问对象。
应用程序域是一个操作系统进程中一个或多个应用程序所驻留的分区。同一应用程序域中的对象直接通信。不同应用程序域中的对象的通信方式有两种:一种是跨应用程序域边界传输对象副本,一种是使用代理交换消息。
MarshalByRefObject 是通过使用代理交换消息来跨应用程序域边界进行通信的对象的基类。不是从 MarshalByRefObject 继承的对象根据值隐式封送。当远程应用程序引用根据值封送的对象时,将跨应用程序域边界传递该对象的副本。
MarshalByRefObject 对象在本地应用程序域的边界内可直接访问。远程应用程序域中的应用程序首次访问 MarshalByRefObject 时,会向该远程应用程序传递代理。对该代理后面的调用将封送回驻留在本地应用程序域中的对象。
当跨应用程序域边界使用类型时,类型必须是从 MarshalByRefObject 继承的,而且由于对象的成员在创建它们的应用程序域之外无法使用,所以不得复制对象的状态。

2) ChannelServices 类:

提供帮助进行远程处理信道注册、解析和 URL 发现的静态方法。
信道跨远程处理边界(例如 AppDomains、进程和计算机)在应用程序之间传输消息。这些交叉可以是入站和出站的。信道可以在终结点上侦听入站消息,向终结点发送出站消息,或同时进行这两种操作。这在运行库中提供一个可扩展性点,以便插入各种协议,即使运行库可能并不在信道的另一端。运行库对象可用于公开各种语义和实体。信道提供可扩展性点以将消息在特定协议间来回转换。

3) TcpChannel 类:

一) Remoting程序的创建(分三步走)[附源代码下载].

1 创建General远程对象

此对象必须继承MarshalByRefObject。
代码如下:
2.创建Server作为"
宿主(host)",以接收客户请求

 1 ExpandedBlockStart.gif ContractedBlock.gif /**/ /// <summary>
 2InBlock.gif    /// 远程对象类
 3ExpandedBlockEnd.gif    /// </summary>

 4 None.gif      public   class  RemoteObject : MarshalByRefObject
 5 ExpandedBlockStart.gifContractedBlock.gif     dot.gif {
 6InBlock.gif        public RemoteObject()
 7ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 8InBlock.gif            Console.WriteLine("I am from Remote Object!");
 9ExpandedSubBlockEnd.gif        }

10InBlock.gif        public string GetClassName(string name)
11ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
12InBlock.gif            return name;
13ExpandedSubBlockEnd.gif        }

14ExpandedBlockEnd.gif    }

 

1)注册通道,下文注册了一个端口号为8000的端口。
   注册后服务器就会监听来自8000端口的请求。
2)注册服务器激活的远程对象


3.创建Client,调用远程对象

 1 ExpandedBlockStart.gif ContractedBlock.gif /**/ /// <summary>
 2InBlock.gif    /// 服务器端
 3ExpandedBlockEnd.gif    /// </summary>

 4 None.gif      public   class  Server
 5 ExpandedBlockStart.gifContractedBlock.gif     dot.gif {
 6InBlock.gif        static void Main(string[] args)
 7ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 8InBlock.gif            //实例化并注册一个TCP通道
 9InBlock.gif            IChannel tcpchannel = new TcpChannel(8000);
10InBlock.gif            ChannelServices.RegisterChannel(tcpchannel, true);
11InBlock.gif
12InBlock.gif            //将服务端上的对象类型注册为已知类型
13InBlock.gif            RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteObject), "GetObject", WellKnownObjectMode.Singleton);
14InBlock.gif
15InBlock.gif            Console.WriteLine("Press Enter Key to Exit!");
16InBlock.gif            Console.ReadLine();
17InBlock.gif      
18ExpandedSubBlockEnd.gif        }

19ExpandedBlockEnd.gif    }

 

1)注册通道
2)根据URL得到对象代理
3)使用代理调用远程对象

 1 ExpandedBlockStart.gif ContractedBlock.gif /**/ /// <summary>
 2InBlock.gif    /// 客户端
 3ExpandedBlockEnd.gif    /// </summary>

 4 None.gif      public   class  Client
 5 ExpandedBlockStart.gifContractedBlock.gif     dot.gif {
 6InBlock.gif        static void Main(string[] args)
 7ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 8InBlock.gif            //实例化并注册一个TCP通道
 9InBlock.gif            IChannel tcpChannel = new TcpChannel();
10InBlock.gif            ChannelServices.RegisterChannel(tcpChannel, true);
11InBlock.gif
12InBlock.gif            //激活远程对象
13InBlock.gif            RemoteObject obj = (RemoteObject)Activator.GetObject(typeof(RemotingDemo.RemoteObject),"tcp://localhost:8000/GetObject");
14InBlock.gif
15InBlock.gif            if (obj == null)
16ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
17InBlock.gif                Console.WriteLine("Could not get Tcp Server");
18ExpandedSubBlockEnd.gif            }

19InBlock.gif
20InBlock.gif            //调用远程方法
21InBlock.gif            Console.WriteLine("Client TCP GetClassName: {0}",obj.GetClassName("ring1981"));
22InBlock.gif
23InBlock.gif            Console.ReadLine();
24ExpandedSubBlockEnd.gif        }

25ExpandedBlockEnd.gif    }


到此为止,Remoting应用程序建立完毕!

运行结果:
remoting_result.GIF
上面的例子是全部通过编程实现,在下篇文章里里我会介绍如何通过配置文件实现。

二)关于运行Remoting程序的一点说明

由于不少初学者说按"F5"看不到这样的结果,其实是没有学会如何运行这种多个项目,出现多个Dos窗口结果的工程。

我就附带介绍一下如何运行上面这个例子吧:
第一步: 选择"Debug"->"Start Debuging"或"Debug->Start without Debug"都行,点击后会出现一个Dos窗口显示结果。
第二步: 选择"Soluting Explorer"下的"Client"项目,选中后点击鼠标右键,点击后出现一个菜单。
第三步: 选择"Debug"->"Start new instance",单击就OK了。
 

二 使用配置文件建立Remoting程序


一) 服务器端配置(app.config)

 1 None.gif < configuration >
 2 None.gif   < system .runtime.remoting >
 3 None.gif     < application >
 4 None.gif       < channels >
 5 None.gif         < channel  ref ="tcp"  port ="8000"   />
 6 None.gif       </ channels >
 7 None.gif       < service >
 8 None.gif         < wellknown  mode ="Singleton"
 9 None.gif                   type ="RemotingDemo.RemoteObject, General"
10 None.gif                   objectUri ="GetObject"   />
11 None.gif       </ service >
12 None.gif     </ application >
13 None.gif   </ system.runtime.remoting >
14 None.gif </ configuration >
15 None.gif


此时服务器端代码为:

 1 ExpandedBlockStart.gif ContractedBlock.gif   /**/ /// <summary>
 2InBlock.gif    /// 服务器端
 3ExpandedBlockEnd.gif    /// </summary>

 4 None.gif      public   class  Server
 5 ExpandedBlockStart.gifContractedBlock.gif     dot.gif {
 6InBlock.gif        static void Main(string[] args)
 7ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{            
 8InBlock.gif            RemotingConfiguration.Configure("server.exe.config"true);
 9InBlock.gif
10InBlock.gif            Console.WriteLine("Press Enter Key to Exit!");
11InBlock.gif            Console.ReadLine();      
12ExpandedSubBlockEnd.gif        }

13ExpandedBlockEnd.gif    }



二) 客户端配置 (client.exe.config)

 1 None.gif < configuration >
 2 None.gif     < system .runtime.remoting >
 3 None.gif         < application >
 4 None.gif             < client >
 5 None.gif                 < wellknown  type ="RemoteObject, General"  url ="tcp://localhost:8000/GetObject"   />
 6 None.gif             </ client >
 7 None.gif             < channels >
 8 None.gif                 < channel  ref ="tcp"  port ="0" ></ channel >
 9 None.gif             </ channels >
10 None.gif         </ application >
11 None.gif     </ system.runtime.remoting >
12 None.gif </ configuration >
13 None.gif


此时客户端的代码为:

ExpandedBlockStart.gif ContractedBlock.gif /**/ /// <summary>
InBlock.gif    
/// 客户端
ExpandedBlockEnd.gif    
/// </summary>
None.gif      public   class  Client
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
InBlock.gif            RemotingConfiguration.Configure(
@"client.exe.config"true);
InBlock.gif            RemoteObject obj 
= new RemoteObject();
InBlock.gif            
if (obj == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(
"Could not get Tcp Server");
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
//调用远程方法
InBlock.gif
            Console.WriteLine("Client TCP GetClassName: {0}",obj.GetClassName("ring1981"));
InBlock.gif
InBlock.gif            Console.ReadLine();
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }



一个标准写全的Remoting Configuration文件应该是如下结构:

 1 None.gif < configuration >
 2 None.gif    < system .runtime.remoting >
 3 None.gif       < application >
 4 None.gif         < lifetime  />
 5 None.gif         < channels  />
 6 None.gif         < service  />
 7 None.gif         < client  />
 8 None.gif       </ application >
 9 None.gif    </ system.runtime.remoting >
10 None.gif </ configuration >
11 None.gif
12 None.gif


接下来结合配置文件介绍一下各结点的具体涉及内容:

一) 生命周期(LifeTime):用于配置对象的生命周期.

ATTRIBUTE

DESCRIPTION

leaseTime

The initial time to live (TTL) for your objects (默认5 分钟)

sponsorshipTimeout

The time to wait for a sponsor's reply (默认2 分钟)

renewOnCallTime

The time to add to an object's TTL when a method is called (默认2 分钟)

leaseManagerPollTime

The interval in which your object's TTL will be checked (默认10 秒)

ATTRIBUTE

DESCRIPTION

ref

引用先前定义好的通道("tcp"或"http"),或者引用先前在配置文件里定义好的通道

displayName

此属性只用于.NET Framework配置工具

type

该属性在ref没有定义时,是托管的。Attribute that is mandatory when ref has not been specified. Contains the exact type (namespace, classname, assembly) of the channel's implementation. When the assembly is in the GAC, you have to specify version, culture, and public key information as well.

port

端口号

ATTRIBUTE

DESCRIPTION

type

写法如"<namespace>.<classname>, <assembly>"。程序集中已发布类的类型。

mode

指出具体对象调用类型("Singleton" 或"SingleCall").

objectUri

用于呼叫对象的终端URI。当对象宿主在IIS中,URI需以.soap或.rem结尾。

displayName

用于.NET Framework Configuration Tool中。

ATTRIBUTE

DESCRIPTION

type

写法如"<namespace>.<classname>, <assembly>"。程序集中已发布类的类型。

提供使用 TCP 协议传输消息的信道实现。

 

转载于:https://www.cnblogs.com/Ring1981/archive/2006/07/20/451624.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Remoting客户是指使用远程调用技术进行通信的客户端。远程调用是一种在分布式系统中的通信方式,它允许在不同的计算机之间进行方法的调用和数据的传输。 Remoting客户通过建立与远程服务器的连接,可以像调用本地对象一样调用远程对象的方法。这样的客户端可以将请求发送给远程服务器,获得结果并将其返回给调用方。Remoting客户端可以通过网络传输数据,实现跨平台和跨语言的通信。 Remoting客户端通常通过使用远程代理(Proxy)来访问远程对象。远程代理充当了客户端和服务器之间的中间层,隐藏了底层通信的细节。客户端通过远程代理来调用远程对象的方法,而不需要了解底层的网络通信协议或者具体的通信细节。 Remoting客户端还可以通过配置文件或者编程方式来指定远程服务器的地址和端口以及其他的通信参数。这样的配置方式使得客户端可以灵活地连接到不同的远程服务器上。 在使用Remoting客户端时,需要注意网络的稳定性和安全性。网络不稳定可能造成通信中断或者性能降低,而网络安全问题可能导致数据泄露或者被篡改。因此,在设计和实现Remoting客户端时,需要考虑这些问题,并采取相应的措施。 总之,Remoting客户端是一种使用远程调用技术进行通信的客户端,它可以像调用本地对象一样调用远程对象的方法。通过使用远程代理,客户端可以隐藏底层通信的细节,并通过配置文件或者编程方式连接到远程服务器。在使用Remoting客户端时,需要注意网络的稳定性和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值