在分布系统中,远程对象需要跨越应用程序域进行传递,因此其表示方式会有所不同。基于性能和数据共享等原因考虑,Remoting 中远程对象可以是 "值封送对象(MBV)" 或 "引用封送对象(MBR)"。
MBV 机制类似于 Web 无状态请求,服务器创建对象实例传递给信道发送到客户端,而后服务器端不再继续维护其状态和生存期。而 MBR 则在其生存期内一直存活在服务器程序域中,客户端只是通过代理对象来完成调用消息传递,客户端可以通过相关接口来延长远程对象的生存期。
实现 MBV 一般通过 SerializableAttribute 特性,或者实现 ISerializable 接口。运行下面的例子,我们会发现远程对象在客户端程序域内,并且不是代理对象。
在分布系统中,远程对象需要跨越应用程序域进行传递,因此其表示方式会有所不同。基于性能和数据共享等原因考虑,Remoting 中远程对象可以是 "值封送对象(MBV)" 或 "引用封送对象(MBR)"。
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
MBV 机制类似于 Web 无状态请求,服务器创建对象实例传递给信道发送到客户端,而后服务器端不再继续维护其状态和生存期。而 MBR 则在其生存期内一直存活在服务器程序域中,客户端只是通过代理对象来完成调用消息传递,客户端可以通过相关接口来延长远程对象的生存期。
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
实现 MBV 一般通过 SerializableAttribute 特性,或者实现 ISerializable 接口。运行下面的例子,我们会发现远程对象在客户端程序域内,并且不是代理对象。
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.CompilerServices;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Messaging;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
namespace Learn.Library.Remoting
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
public class RemotingTest2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 远程类型
/// </summary>
[Serializable]
public class Data
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
private int i;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public int I
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return i; }
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ i = value; }
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void Where()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Console.WriteLine("{0} in {1}", this.GetType().Name, AppDomain.CurrentDomain.FriendlyName);
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 服务器端代码
/// </summary>
static void Server()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// 创建新的应用程序域,以便模拟分布结构。
AppDomain server = AppDomain.CreateDomain("server");
server.DoCallBack(delegate
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// 创建并注册信道
TcpServerChannel channel = new TcpServerChannel(801);
ChannelServices.RegisterChannel(channel, false);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 注册远程类型
RemotingConfiguration.ApplicationName = "test";
RemotingConfiguration.RegisterActivatedServiceType(typeof(Data));
});
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 客户端代码
/// </summary>
static void Client()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// 创建并注册信道
TcpClientChannel channel = new TcpClientChannel();
ChannelServices.RegisterChannel(channel, false);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 注册远程类型
RemotingConfiguration.RegisterActivatedClientType(typeof(Data), "tcp://localhost:801/test");
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 创建远程对象并调用其方法
Data data = Activator.CreateInstance(typeof(Data)) as Data;
data.Where();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 判断是否是代理
Console.WriteLine(RemotingServices.IsTransparentProxy(data));
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
static void Main()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Server();
Client();
}
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
输出:
Data in Learn.CUI.vshost.exe
False
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
MBR 则要求继承自 MarshalByRefObject 或 ContextBoundObject。继承自 ContextBoundObject 的远程对象,可以包含其执行上下文,比如事务等等,其性能不如 MarshalByRefObject。下面的例子中,远程对象依旧在服务器程序域内执行,客户端只是一个代理对象在转发调用。
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.CompilerServices;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Messaging;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
namespace Learn.Library.Remoting
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
public class RemotingTest2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 远程类型
/// </summary>
public class Data : MarshalByRefObject
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
private int i;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public int I
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return i; }
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ i = value; }
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void Where()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Console.WriteLine("{0} in {1}", this.GetType().Name, AppDomain.CurrentDomain.FriendlyName);
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 服务器端代码
/// </summary>
static void Server()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// 创建新的应用程序域,以便模拟分布结构。
AppDomain server = AppDomain.CreateDomain("server");
server.DoCallBack(delegate
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// 创建并注册信道
TcpServerChannel channel = new TcpServerChannel(801);
ChannelServices.RegisterChannel(channel, false);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 注册远程类型
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Data), "data",
WellKnownObjectMode.Singleton);
});
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// 客户端代码
/// </summary>
static void Client()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// 创建并注册信道
TcpClientChannel channel = new TcpClientChannel();
ChannelServices.RegisterChannel(channel, false);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 创建远程对象并调用其方法
Data data = (Data)Activator.GetObject(typeof(Data), "tcp://localhost:801/data");
data.Where();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 判断是否是代理
Console.WriteLine(RemotingServices.IsTransparentProxy(data));
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
static void Main()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Server();
Client();
}
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
输出:
Data in server
True
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
MBV 传递完整的副本到客户端,而后的所有调用都是在客户端程序域内进行,不再需要跨域的往返过程。但完整复制和序列化需要更多的资源和往返时间,因此不适合较大的对象,同时无法在多个客户端间共享信息。而 MBR 的所有调用都是通过代理进行的,因此往返过程比较多,但因执行过程都在服务器端进行,其整体性能还是非常高的。在系统设计时可以针对不同的应用采取不同的选择。
posted on
2007-06-05 09:29
编程山人
阅读(
346)
评论()
编辑
收藏
举报