[Remoting专题系列] 二:远程对象

None.gif 在分布系统中,远程对象需要跨越应用程序域进行传递,因此其表示方式会有所不同。基于性能和数据共享等原因考虑,Remoting 中远程对象可以是  " 值封送对象(MBV) "  或  " 引用封送对象(MBR) "
None.gif
None.gifMBV 机制类似于 Web 无状态请求,服务器创建对象实例传递给信道发送到客户端,而后服务器端不再继续维护其状态和生存期。而 MBR 则在其生存期内一直存活在服务器程序域中,客户端只是通过代理对象来完成调用消息传递,客户端可以通过相关接口来延长远程对象的生存期。
None.gif
None.gif实现 MBV 一般通过 SerializableAttribute 特性,或者实现 ISerializable 接口。运行下面的例子,我们会发现远程对象在客户端程序域内,并且不是代理对象。
None.gif
None.gif
using  System;
None.gif
using  System.Collections;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Reflection;
None.gif
using  System.Runtime.Serialization;
None.gif
using  System.Runtime.Serialization.Formatters;
None.gif
using  System.Runtime.Serialization.Formatters.Binary;
None.gif
using  System.Runtime.CompilerServices;
None.gif
using  System.Runtime.Remoting;
None.gif
using  System.Runtime.Remoting.Channels;
None.gif
using  System.Runtime.Remoting.Channels.Tcp;
None.gif
using  System.Runtime.Remoting.Messaging;
None.gif
None.gif
namespace  Learn.Library.Remoting
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif  
public class RemotingTest2
ExpandedSubBlockStart.gifContractedSubBlock.gif  
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// 远程类型
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    [Serializable]
InBlock.gif    
public class Data
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      
private int i;
InBlock.gif
InBlock.gif      
public int I
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn i; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ i = value; }
ExpandedSubBlockEnd.gif      }

InBlock.gif
InBlock.gif      
public void Where()
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif        Console.WriteLine(
"{0} in {1}"this.GetType().Name, AppDomain.CurrentDomain.FriendlyName);
ExpandedSubBlockEnd.gif      }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// 服务器端代码
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    static void Server()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      
// 创建新的应用程序域,以便模拟分布结构。
InBlock.gif
      AppDomain server = AppDomain.CreateDomain("server");
InBlock.gif      server.DoCallBack(
delegate
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif        
// 创建并注册信道
InBlock.gif
        TcpServerChannel channel = new TcpServerChannel(801);
InBlock.gif        ChannelServices.RegisterChannel(channel, 
false);
InBlock.gif
InBlock.gif        
// 注册远程类型
InBlock.gif
        RemotingConfiguration.ApplicationName = "test";
InBlock.gif        RemotingConfiguration.RegisterActivatedServiceType(
typeof(Data));
ExpandedSubBlockEnd.gif      }
);
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// 客户端代码
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    static void Client()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      
// 创建并注册信道
InBlock.gif
      TcpClientChannel channel = new TcpClientChannel();
InBlock.gif      ChannelServices.RegisterChannel(channel, 
false);
InBlock.gif
InBlock.gif      
// 注册远程类型
InBlock.gif
      RemotingConfiguration.RegisterActivatedClientType(typeof(Data), "tcp://localhost:801/test");
InBlock.gif
InBlock.gif      
// 创建远程对象并调用其方法
InBlock.gif
      Data data = Activator.CreateInstance(typeof(Data)) as Data;
InBlock.gif      data.Where();
InBlock.gif
InBlock.gif      
// 判断是否是代理
InBlock.gif
      Console.WriteLine(RemotingServices.IsTransparentProxy(data));
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
static void Main()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      Server();
InBlock.gif      Client();
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockEnd.gif  }

ExpandedBlockEnd.gif}

None.gif
None.gif输出:
None.gifData 
in  Learn.CUI.vshost.exe
None.gifFalse
None.gif
None.gifMBR 则要求继承自 MarshalByRefObject 或 ContextBoundObject。继承自 ContextBoundObject 的远程对象,可以包含其执行上下文,比如事务等等,其性能不如 MarshalByRefObject。下面的例子中,远程对象依旧在服务器程序域内执行,客户端只是一个代理对象在转发调用。
None.gif
None.gif
using  System;
None.gif
using  System.Collections;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Reflection;
None.gif
using  System.Runtime.Serialization;
None.gif
using  System.Runtime.Serialization.Formatters;
None.gif
using  System.Runtime.Serialization.Formatters.Binary;
None.gif
using  System.Runtime.CompilerServices;
None.gif
using  System.Runtime.Remoting;
None.gif
using  System.Runtime.Remoting.Channels;
None.gif
using  System.Runtime.Remoting.Channels.Tcp;
None.gif
using  System.Runtime.Remoting.Messaging;
None.gif
None.gif
namespace  Learn.Library.Remoting
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif  
public class RemotingTest2
ExpandedSubBlockStart.gifContractedSubBlock.gif  
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// 远程类型
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public class Data : MarshalByRefObject
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      
private int i;
InBlock.gif
InBlock.gif      
public int I
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
get dot.gifreturn i; }
ExpandedSubBlockStart.gifContractedSubBlock.gif        
set dot.gif{ i = value; }
ExpandedSubBlockEnd.gif      }

InBlock.gif
InBlock.gif      
public void Where()
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif        Console.WriteLine(
"{0} in {1}"this.GetType().Name, AppDomain.CurrentDomain.FriendlyName);
ExpandedSubBlockEnd.gif      }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// 服务器端代码
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    static void Server()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      
// 创建新的应用程序域,以便模拟分布结构。
InBlock.gif
      AppDomain server = AppDomain.CreateDomain("server");
InBlock.gif      server.DoCallBack(
delegate
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif        
// 创建并注册信道
InBlock.gif
        TcpServerChannel channel = new TcpServerChannel(801);
InBlock.gif        ChannelServices.RegisterChannel(channel, 
false);
InBlock.gif
InBlock.gif        
// 注册远程类型
InBlock.gif
        RemotingConfiguration.RegisterWellKnownServiceType(typeof(Data), "data",
InBlock.gif          WellKnownObjectMode.Singleton);
ExpandedSubBlockEnd.gif      }
);
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// 客户端代码
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    static void Client()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      
// 创建并注册信道
InBlock.gif
      TcpClientChannel channel = new TcpClientChannel();
InBlock.gif      ChannelServices.RegisterChannel(channel, 
false);
InBlock.gif
InBlock.gif      
// 创建远程对象并调用其方法
InBlock.gif
      Data data = (Data)Activator.GetObject(typeof(Data), "tcp://localhost:801/data");
InBlock.gif      data.Where();
InBlock.gif
InBlock.gif      
// 判断是否是代理
InBlock.gif
      Console.WriteLine(RemotingServices.IsTransparentProxy(data));
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
static void Main()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif      Server();
InBlock.gif      Client();
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockEnd.gif  }

ExpandedBlockEnd.gif}

None.gif
None.gif输出:
None.gifData 
in  server
None.gifTrue
None.gif
None.gifMBV 传递完整的副本到客户端,而后的所有调用都是在客户端程序域内进行,不再需要跨域的往返过程。但完整复制和序列化需要更多的资源和往返时间,因此不适合较大的对象,同时无法在多个客户端间共享信息。而 MBR 的所有调用都是通过代理进行的,因此往返过程比较多,但因执行过程都在服务器端进行,其整体性能还是非常高的。在系统设计时可以针对不同的应用采取不同的选择。 

转载于:https://www.cnblogs.com/nbwzy/archive/2007/06/05/771580.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值