`
leonardleonard
  • 浏览: 820896 次
社区版块
存档分类
最新评论

[Remoting] 二:远程对象

阅读更多
在分布系统中,远程对象需要跨越应用程序域进行传递,因此其表示方式会有所不同。基于性能和数据共享等原因考虑,Remoting 中远程对象可以是 "值封送对象(MBV)" 或 "引用封送对象(MBR)"。

MBV 机制类似于 Web 无状态请求,服务器创建对象实例传递给信道发送到客户端,而后服务器端不再继续维护其状态和生存期。而 MBR 则在其生存期内一直存活在服务器程序域中,客户端只是通过代理对象来完成调用消息传递,客户端可以通过相关接口来延长远程对象的生存期。

实现 MBV 一般通过 SerializableAttribute 特性,或者实现 ISerializable 接口。运行下面的例子,我们会发现远程对象在客户端程序域内,并且不是代理对象。
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;

namespace Learn.Library.Remoting
{
  public class RemotingTest2
  {
    /// <summary>
    /// 远程类型
    /// </summary>
    [Serializable]
    public class Data
    {
      private int i;

      public int I
      {
        get { return i; }
        set { i = value; }
      }

      public void Where()
      {
        Console.WriteLine("{0} in {1}", this.GetType().Name, AppDomain.CurrentDomain.FriendlyName);
      }
    }

    /// <summary>
    /// 服务器端代码
    /// </summary>
    static void Server()
    {
      // 创建新的应用程序域,以便模拟分布结构。
      AppDomain server = AppDomain.CreateDomain("server");
      server.DoCallBack(delegate
      {
        // 创建并注册信道
        TcpServerChannel channel = new TcpServerChannel(801);
        ChannelServices.RegisterChannel(channel, false);

        // 注册远程类型
        RemotingConfiguration.ApplicationName = "test";
        RemotingConfiguration.RegisterActivatedServiceType(typeof(Data));
      });
    }

    /// <summary>
    /// 客户端代码
    /// </summary>
    static void Client()
    {
      // 创建并注册信道
      TcpClientChannel channel = new TcpClientChannel();
      ChannelServices.RegisterChannel(channel, false);

      // 注册远程类型
      RemotingConfiguration.RegisterActivatedClientType(typeof(Data), "tcp://localhost:801/test");

      // 创建远程对象并调用其方法
      Data data = Activator.CreateInstance(typeof(Data)) as Data;
      data.Where();

      // 判断是否是代理
      Console.WriteLine(RemotingServices.IsTransparentProxy(data));
    }

    static void Main()
    {
      Server();
      Client();
    }
  }
}

输出:
Data in Learn.CUI.vshost.exe
False

MBR 则要求继承自 MarshalByRefObject 或 ContextBoundObject。继承自 ContextBoundObject 的远程对象,可以包含其执行上下文,比如事务等等,其性能不如 MarshalByRefObject。下面的例子中,远程对象依旧在服务器程序域内执行,客户端只是一个代理对象在转发调用。
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;

namespace Learn.Library.Remoting
{
  public class RemotingTest2
  {
    /// <summary>
    /// 远程类型
    /// </summary>
    public class Data : MarshalByRefObject
    {
      private int i;

      public int I
      {
        get { return i; }
        set { i = value; }
      }

      public void Where()
      {
        Console.WriteLine("{0} in {1}", this.GetType().Name, AppDomain.CurrentDomain.FriendlyName);
      }
    }

    /// <summary>
    /// 服务器端代码
    /// </summary>
    static void Server()
    {
      // 创建新的应用程序域,以便模拟分布结构。
      AppDomain server = AppDomain.CreateDomain("server");
      server.DoCallBack(delegate
      {
        // 创建并注册信道
        TcpServerChannel channel = new TcpServerChannel(801);
        ChannelServices.RegisterChannel(channel, false);

        // 注册远程类型
        RemotingConfiguration.RegisterWellKnownServiceType(typeof(Data), "data",
          WellKnownObjectMode.Singleton);
      });
    }

    /// <summary>
    /// 客户端代码
    /// </summary>
    static void Client()
    {
      // 创建并注册信道
      TcpClientChannel channel = new TcpClientChannel();
      ChannelServices.RegisterChannel(channel, false);

      // 创建远程对象并调用其方法
      Data data = (Data)Activator.GetObject(typeof(Data), "tcp://localhost:801/data");
      data.Where();

      // 判断是否是代理
      Console.WriteLine(RemotingServices.IsTransparentProxy(data));
    }

    static void Main()
    {
      Server();
      Client();
    }
  }
}

输出:
Data in server
True

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

相关推荐

    Remoting简单远程对象实例

    这个“Remoting简单远程对象实例”着重于介绍如何创建和使用远程对象,使得一个应用程序能够调用另一个应用程序的对象方法,就像它们在同一个进程中一样。 在.NET Remoting中,远程对象被定义为具有公共接口的类,...

    Remoting入门程序

    1.定义远程对象:继承自MarshaByRefObject 2.创建一个Server端作为宿主 注册远程对象(作为对象的宿主) 注册通道 3.创建客户端 注册通道 通过URL获取Server端远程对象的代理 通过代理操作远程对象,使得在...

    remoting从入门到精通教程

    3. **接近本地调用的体验**:Remoting提供的远程对象调用体验几乎与本地对象调用无异,大大降低了分布式应用的开发难度。 4. **状态保持能力**:Remoting支持远程对象的状态保持,这对于需要持续会话的场景尤为关键...

    Remoting进行远程通迅

    .NET Remoting提供了一种简单有效的方式来实现远程对象的交互。通过本篇文章的学习,我们可以了解到如何构建一个基本的远程服务端和客户端,以及如何通过TCP通道来进行通信。这对于开发分布式应用非常有用,特别是在...

    .NET Remoting 实现远程数据库访问源码

    3. **客户端调用**:客户端通过Remoting的`Activator`类实例化服务器端的远程对象,然后就可以像调用本地对象一样调用其方法。客户端并不需要知道服务器端的具体实现,只需要知道如何通过Remoting接口进行通信。 4....

    remoting远程方法回调实例

    ### remoting远程方法回调实例详解 #### 一、概述 在.NET Remoting中,远程方法回调是一种非常重要的机制,它允许服务器端对象调用客户端对象的方法或访问客户端对象的属性。这种方式增强了分布式应用的交互性与...

    通过remoting和Activator远程连接服务器并调用方法

    Activator类是.NET框架的一部分,它提供了一种动态创建对象实例的方法,包括远程对象。 以下是实现此功能的步骤: 1. **设置服务器端:** - 创建一个实现了特定接口的类,该接口定义了要在客户端调用的方法。 - ...

    Remoting技术

    3. 对象状态保持:Remoting支持保持远程对象的状态,这在某些场景下非常有用。 4. 应用程序无限制:无论控制台应用、WinForm、IIS还是Windows服务,都可以承载远程对象。 然而,Remoting也有其缺点: 1. 平台限制:...

    remoting经典教程 附源码示例

    1. 创建远程对象: 定义一个名为 `MyObject` 的公共类,继承自 `MarshalByRefObject` 类。`MarshalByRefObject` 是 Remoting 中的关键类,允许对象引用跨进程边界传递。在 `MyObject` 类中定义一个 `Add` 方法,接收...

    c# 实现远程调用(rpc) remoting

    在提供的压缩包文件中,可能包含了三个示例项目:"remotedll"可能是一个包含远程对象实现的DLL文件,"remotecli"可能是客户端应用程序,用于调用远程对象,而"remoteser"可能是服务器端应用程序,负责启动和激活远程...

    remoting学习

    2. 远程对象:在Remoting中,一个对象可以在一个进程内创建,然后被另一个进程访问,就像本地对象一样。这需要将对象封装为可以跨进程传输的类型。 3. 通道:Remoting通过通道来实现跨进程通信,通道负责对象的序列...

    c#.net remoting 实例 范例

    - **对象透明性**:Remoting使远程对象看起来就像是本地对象一样调用,隐藏了底层的网络通信细节。 - **生命周期管理**:远程对象可以在服务器端被持久化或瞬态存在,根据激活方式不同,生命周期由客户端或服务器...

    c#remoting简单例子

    在.NET Remoting中,你可以创建一个远程对象,该对象可以在本地运行,也可以在远程计算机上运行,而客户端代码无需关心对象的实际位置。Remoting提供了一种高效、灵活的方式来实现跨进程通信,使得对象调用就像调用...

    NET的远程对象编程示例代码

    .NET的远程对象编程(Remoting)是微软.NET框架提供的一种技术,它允许应用程序在不同的进程或甚至不同的计算机之间共享对象。这项技术的核心在于使对象能够跨越进程和网络边界,仿佛它们在同一环境中运行。通过.NET...

    Net Remoting 入门与提高

    二、远程对象的定义 远程对象是能够被远程访问的.NET对象。它们需要继承自System.MarshalByRefObject类,这是因为这个基类支持跨AppDomain的引用。为了使对象可远程访问,还需要使用Attribute标记来指定其配置信息,...

    .NET Remoting

    4. **代理对象**:.NET Remoting使用代理对象来代表远程对象,代理对象在客户端接收方法调用并转发到实际的远程对象。 5. **生命周期管理**:开发者可以控制远程对象的生命周期,包括何时创建、何时销毁,以及如何...

    Remoting实例

    在Remoting中,每个远程对象都驻留在其自己的AppDomain中,提供了安全性、稳定性以及资源管理。 2. **配置文件配置**:配置文件是设置Remoting通信的关键部分。通过修改或创建如`app.config`或`web.config`等配置...

    remoting实例

    5. **对象生存期管理**:.NET Remoting提供了对远程对象生存期的控制,包括临时对象和持久对象。临时对象在无引用时会被立即释放,而持久对象即使没有引用也会保持活动状态,直到其生命周期结束。 6. **安全性**:...

    VB.NET Remoting 技术手册

    3. 远程对象:通过Remoting可以创建远程对象实例,这些对象可以在不同的AppDomain或机器上被调用。 4. 泛型服务器(Singleton)与激活服务器(Singleton):泛型服务器允许多个客户端共享同一对象实例,而激活服务器...

    VB_NET Remoting 高级技术手册

    1. 定义可序列化的远程对象:在VB.NET中,使用`MarshalByRefObject`作为基类,创建可以跨应用程序域访问的类。 2. 注册远程对象:通过配置文件或代码动态注册远程对象,指定其激活方式、接口类型和访问地址。 3. ...

Global site tag (gtag.js) - Google Analytics