现在的位置: 首页 > 综合 > 正文

NET Framework 远程处理

2013年08月07日 ⁄ 综合 ⁄ 共 9916字 ⁄ 字号 评论关闭

NET Framework 远程处理概述

NET Framework 远程处理结构

 

.NET 远程处理基础结构是进程间通信的抽象方法。系统的大部分在运行时无须关心。例如,可以通过值传递或可以复制的对象是自动在不同应用程序域中或不同计算机上的应用程序之间传递的。只需将自定义类标记为可序列化便可使它工作。

然而,远程处理系统的真正优点在于它具有的通信功能,它能够使位于不同应用程序域中的对象相互通信,还能够使位于不同进程中的对象相互通信,即使这些进程使用的传输协议、序列化格式、对象生存期方案和对象创建模式不同,也是如此。此外,远程处理使您可以出于任何原因在通信进程的几乎任何阶段进行干预。

无论您已经实现了一些分布式应用程序,还是只对将组件移动到其他计算机上以增加程序的可伸缩性感兴趣,您都可以非常容易地将远程处理系统理解为一般性的进程间通信系统,它具有一些能够轻松处理大多数方案的默认实现。下面的讨论从使用远程处理进行进程间通信的基础知识开始。

副本与引用

进程间通信需要具备以下条件:存在向进程外的调用方提供功能的服务器对象,存在对服务器对象进行调用的客户端,并具有一个将调用从一端运送到另一端的传输机制。服务器方法的地址是逻辑地址,并且可在一个进程中正常工作,但不能在其他客户端进程中正常工作。要解决此问题,客户端可以通过创建对象的完整副本,然后将该副本移动到客户端进程来调用服务器对象,这样在该客户端进程中就可以直接调用该副本的方法了。

然而,许多对象无法或不应复制和移动到某个其他进程来执行。具有许多方法的非常大的对象不适合复制到或通过值传递到其他进程。通常,客户端仅需要由服务器对象上的一个或几个方法返回的信息。复制整个服务器对象将是对带宽以及客户端内存和处理时间的浪费,因为这种复制将复制可能与客户端需求无关的大量内部信息或可执行结构。另外,许多对象公开公共功能,但是需要用于内部执行的私有数据。复制这些对象会使未经授权的客户端能够查看内部数据,从而造成安全隐患。最后,某些对象使用的数据无法以任何可理解的方式复制。例如,FileInfo 对象包含一个对操作系统文件的引用,此文件在服务器进程的内存中具有唯一的地址。可以复制这个地址,但它在另一进程中将永远不会具有任何意义。

在这些情况下,服务器进程应当向客户端进程传递一个对服务器对象的引用,而不是传递该对象的副本。客户端可以使用此引用来调用服务器对象。这些调用不在客户端进程中执行。相反,远程处理系统收集关于调用的所有信息并将其发送到服务器进程,在该进程中,将解释这些信息并查找正确的服务器对象,然后代表客户端对象向该服务器对象发出调用。然后,调用的结果被发送回客户端进程以返回到客户端。带宽仅用于关键的信息:调用、调用参数以及任何返回值或异常。

简化的远程处理结构

使用对象引用在服务器对象和客户端之间进行通信是远程处理的核心。但是,远程处理结构为程序员提供了更为简单的过程。如果正确配置了客户端,只需要使用 new(或托管编程语言中的实例创建函数)创建远程对象的新实例。客户端接收对服务器对象的引用,然后就可以像该对象位于您的进程中而不是运行在另外一台计算机上一样调用其方法。远程处理系统使用代理对象来产生服务器对象位于客户端进程中的效果。代理是将它们自身显示为某个其他对象的临时代理对象。当客户端创建远程类型的实例时,远程处理基础结构将创建对于客户端来说与远程类型完全相同的代理对象。客户端调用此代理上的方法,而远程处理系统则接收调用,将其路由到服务器进程,调用服务器对象,并将返回值返回到客户端代理,而客户端代理将结果返回到客户端。

远程调用必须以某种方式在客户端和服务器进程之间传送。如果要自己生成远程处理系统,可以从学习网络编程、各种各样的协议和序列化格式规范开始。在 .NET 远程处理系统中,打开网络连接和使用特定协议将字节发送到接收应用程序所需的基础技术的组合被表示为传输信道。

信道是一个承载数据流、根据特定网络协议创建包并将该包发送到另一台计算机的类型。某些信道只能接收信息,另外一些信道只能发送信息,还有一些信道(例如默认的 TcpChannelHttpChannel 类)则既可以发送、又可以接收。

虽然服务器进程了解有关每个唯一类型的一切信息,但是客户端仅知道它需要对其他应用程序域(可能在其他计算机上)中的某个对象的引用。从服务器应用程序域之外的世界中,URL 可定位该对象。向外部世界表示唯一类型的 URL 是激活 URL,它们确保远程调用是针对正确类型发出的。有关更多详细信息,请参见激活 URL

完整的远程处理系统设计

假定您的应用程序在一台计算机上运行,而您想使用由存储在另一台计算机上的类型公开的功能。下图显示常规的远程处理过程。

 

远程处理过程

 

远程处理过程

如果关系两端均正确配置,则客户端仅创建一个服务器类的新实例。远程处理系统创建一个表示该类的代理对象,并向客户端对象返回一个对该代理的引用。当客户端调用方法时,远程处理基础结构将处理调用,检查类型信息,并通过信道将该调用发送到服务器进程。侦听信道获得该请求并将其转发给服务器远程处理系统,服务器远程处理系统查找(或在必要时创建)并调用被请求的对象。然后,此过程将反向进行,服务器远程处理系统将响应捆绑成消息并由服务器信道发送到客户端信道。最后,客户端远程处理系统通过代理将调用的结果返回给客户端对象。

为使此过程工作只需要非常少的实际代码,但应当认真考虑关系的设计和配置。即使代码完全正确,仍然可能因为 URL 或端口号不正确而失败。有关更多信息,请参见配置

虽然远程处理进程的这种高级别概述相当简单,但低级别的详细信息可能是非常复杂的。其他主题中提供了对远程处理的主要元素更为深入的讨论,如下面所列出的主题所示。

请参见

 

.NET 远程处理使您能够轻松地构建大范围分布式应用程序,而不管应用程序组件是全部集中在一台计算机上还是分布在世界各地。您可以生成这样的客户端应用程序:它们使用同一台计算机(或可通过网络达到的其他任何计算机)上的其他进程中的对象。您还可以使用 .NET 远程处理与同一进程中的其他应用程序域进行通信。(有关应用程序域编程的详细信息,请参见对应用程序域进行编程。)

.NET 远程处理为进程间通信提供了一种抽象的方法,它将可远程处理的对象与特定客户端或服务器应用程序域以及特定的通信机制隔离开来。因此,这很灵活且很容易自定义。可以用一种通信协议替换另一种通信协议,或者用一种序列化格式替换另一种序列化格式,而不必重新编译客户端或服务器。此外,远程处理系统假定没有特别的应用程序模型。可以从 Web 应用程序、控制台应用程序、Windows 服务,即差不多可以从希望使用的任何程序中进行通信。远程处理服务器也可以是任何类型的应用程序域。任何应用程序都可以承载远程处理对象并向其计算机或网络上的任何客户端提供服务。

Note注意

出于安全原因,强烈建议您通过安全信道公开远程处理终结点。永远不要向 Internet 公开不安全的远程处理终结点。

要使用 .NET 远程处理生成让两个组件在其中跨越应用程序域边界直接通信的应用程序,只需生成以下对象:

  • 可远程处理的对象。

  • 侦听对该对象的请求的宿主应用程序域。

  • 对该对象发出请求的客户端应用程序域。

即使在复杂的多客户端或多服务器应用程序中,仍可以认为 .NET 远程处理具有这一特性。宿主和客户端应用程序也必须用远程处理基础结构来进行配置,并且您必须了解远程处理基础结构所带来的生存期和激活问题。

 

1.  如何:生成可远程处理的类型

 

要使其他应用程序域中的对象能够使用您的类的实例,该类必须从 MarshalByRefObject 继承。以下过程描述如何创建一个简单的对象,可以通过在其他应用程序域中执行的对象来创建和调用该对象。

// RemotableType.cs
using System;
public class RemotableType : MarshalByRefObject{
  private string StringValue = "This is the RemotableType.";
  public string StringMethod(){
    return StringVale;
  }
}

2,,生成宿主应用程序

 

如何:生成可远程处理的类型主题中定义的 RemotableType 类本身并不特殊。要使其他应用程序域中的对象能够在远程创建该对象的实例,必须生成宿主或侦听器应用程序,以完成以下两项任务:

  • 选择并注册一个信道,该信道是为您处理网络协议和序列化格式的对象。

  • 将您的类型注册到 .NET 远程处理系统,使它可以使用信道来侦听对类型的请求。

.NET Framework 包括两个默认的信道:HttpChannel(它使用 SOAP 格式化)和 TcpChannel(它使用二进制格式化)。开始时最好使用 HttpChannel 信道,因为在某些方案中可以通过防火墙使用该信道而不必打开端口,而且该信道支持标准的安全和身份验证协议。有关选择适合您的方案的信道的更多信息,请参见信道

您可以使用任何类型的应用程序域来生成侦听器应用程序,这些应用程序域包括:Windows 窗体应用程序、ASP.NET Web 应用程序、控制台应用程序、Windows 服务(也称作 Windows NT 服务)或其他任何托管应用程序域。由于远程配置是基于每个应用程序域进行的,因此应用程序域必须处于运行状态才能侦听请求。

Note注意

与 COM 不同,远程处理不会为您启动宿主或服务器应用程序。这是 COM 中的 .NET 远程处理和远程激活之间的重要区别。

配置可以通过编程方式(或者使用应用程序或计算机配置文件)来进行。

远程处理系统使用该文件中的信息来侦听远程请求,并且将远程请求路由到可远程处理类型的实例。该文件指定 Singleton 服务器激活模式、为其侦听的类型的类型名称和程序集,以及对象的统一资源标识符 (URI) 或外部名称。(有关对象 URI 和远程处理的更多详细信息,请参见激活 URL。)该文件还指示远程处理系统使用系统提供的 HttpChannel 来侦听端口 8989 上的请求。

Note注意

虽然前面的配置文件中只有几项设置,但在使用 .NET 远程处理时遇到的大多数问题都与这几项配置有关,原因或者是其中的某些设置不正确,或者是与客户端应用程序的配置设置不匹配。很容易输入错误的名称、忘记端口或者忽略属性。如果您的远程处理应用程序有问题,请首先检查配置设置。

 

3.如何:生成宿主应用程序

 

利用配置文件,您可以更改远程处理配置,而无须重新编译可执行文件等。有关 .NET 远程处理基础结构配置的详细信息,请参见远程处理设置架构

实现一个使用配置文件的简单宿主应用程序域

  1. 创建远程类的配置文件。宿主应用程序必须能够找到用来加载远程类的配置的配置文件,因此,该配置文件应该与宿主应用程序保存在同一目录下,否则,将找不到该配置文件并引发异常。以下代码显示宿主应用程序域的 Listener.exe.config 配置文件。

    <configuration>
       <system.runtime.remoting>
          <application>
             <service>
                <wellknown 
                   mode="Singleton" 
                   type="RemotableType, RemotableType" 
                   objectUri="RemotableType.rem"
                />
             </service>
             <channels>
                <channel ref="http" port="8989"/>
             </channels>
          </application>
       </system.runtime.remoting>
    </configuration>

  2. 导入 System.Runtime.Remoting 命名空间

     

    using System;
    using System.Runtime.Remoting;

  3. 加载配置远程类的配置文件。

     

    public class Listener{
       public static void Main(){
          RemotingConfiguration.Configure("Listener.exe.config");
       }
    }

  4. 使用 .NET Framework SDK 附带的命令行工具将该类编译成宿主或侦听器可执行文件,将该类另存为 Listener.language-extension(或使用您选择的其他文件名,其中的 language-extension 是您要编译的语言)。将该文件保存在用来保存如何:生成可远程处理的类型主题中生成的 RemotableType.dll 的那一目录中。在该目录中的命令提示符处,键入以下命令:

     /r:RemotableType.dll Listener.cs

  5.  

示例

// Listener.cs
using System;
using System.Runtime.Remoting;

public class Listener{
   public static void Main(){
      RemotingConfiguration.Configure("Listener.exe.config");
      Console.WriteLine("Listening for requests. Press Enter to exit...");
      Console.ReadLine();
   }
}

如何:生成客户端应用程序

 

如何:生成可远程处理的类型中我们定义了一个远程类型,在生成宿主应用程序中我们创建了一个应用程序,现在我们要生成该远程类型的客户端,并且要由该应用程序来承载;为此,您的应用程序必须将其自身注册为该远程对象的客户端,然后就像该对象位于客户端的应用程序域中一样调用它。.NET 远程处理系统将截获客户端调用,将其转发到远程对象,并将结果返回到客户端。以下代码过程介绍如何生成简单的远程处理客户端。

生成简单的远程处理客户端

  1. 导入 System.Runtime.Remoting 命名空间

  2. 创建一个客户端配置文件,以便客户端应用程序可以找到远程对象,并将该文件保存到客户端应用程序所在的那个文件夹中。例如,以下配置文件使远程处理系统知道可以在 RemotableType 程序集中找到 RemotableType 远程对象的类型信息,而且此客户端应该尝试创建并使用位于 http://localhost:8989/RemotableType.rem 的 RemotableType 对象。

    <configuration>
       <system.runtime.remoting>
          <application>
             <client>
                <wellknown 
                   type="RemotableType, RemotableType"
                   url="http://localhost:8989/RemotableType.rem"
                />
             </client>
          </application>
       </system.runtime.remoting>
    </configuration>

    有关该配置文件中的 URL 属性的详细信息,请参见激活 URL。如果要在网络上运行该应用程序,必须用远程计算机的名称替换客户端配置中的“localhost”。

    Note注意

    虽然前面的配置文件中只有几项设置,但在使用 .NET 远程处理时遇到的大多数问题都与这几项配置有关,原因或者是其中的某些设置不正确,或者是与客户端应用程序的配置设置不匹配。很容易输入错误的名称、忘记端口或者忽略属性。如果您的远程处理应用程序有问题,请首先检查配置设置。

  3. 将客户端应用程序另存为 Client.language-extension(或者使用您选择的其他文件名,其中的 language-extension 是您要编译的语言)。将该文件保存在保存如何:生成可远程处理的类型主题中生成的 RemotableType.dll 副本的同一个目录中。

    Note注意

    客户端应用程序不应保存在 Listener.exe 应用程序所在的那个目录中。如果保存到同一目录,您将无法确定是否在接收和利用远程引用,因为当应用程序位于同一个目录时,可能会进行程序集和类型解析。

  4. 使用 .NET Framework SDK 附带的命令行工具编译客户端应用程序或调用可执行文件。例如,要编译客户端应用程序 Client.language-extension,请在命令提示符处将目录更改为保存该客户端应用程序的文件夹,然后键入以下命令:

     

    csc /noconfig /r:RemotableType.dll Client.cs

  5. // Client.cs 
    using System;
    using System.Runtime.Remoting;
    
    public class Client{
    
       public static void Main(){
          RemotingConfiguration.Configure("Client.exe.config");
          RemotableType remoteObject = new RemotableType();
          Console.WriteLine(remoteObject.StringMethod());
       }
    }
    

如何:编译和运行基本远程处理应用程序

 

以下过程显示如何使用 .NET Framework SDK 附带的命令行工具编译以下主题中生成的基本远程处理应用程序:如何:生成可远程处理的类型生成宿主应用程序如何:生成客户端应用程序

编译和运行基本远程处理应用程序

  1. 使用在这些主题中指定的名称将所有文件保存在名为 Listener, 的目录中。

  2. Listener 目录中,在命令提示符处键入以下命令:

    Visual Basic
    vbc /t:library RemotableType.vb
    vbc /r:RemotableType.dll Listener.vb
    vbc /r:RemotableType.dll Client.vb
    csc /noconfig /t:library RemotableType.cs
    csc /noconfig /r:RemotableType.dll Listener.cs
    csc /noconfig /r:RemotableType.dll Client.cs
    
  3. 创建一个名为 Client 的子目录。

  4. RemotableType.dllClient.exeClient.exe.config 文件复制到 Client 目录中。

  5. Listener 目录中,在命令提示符处键入 Listener

  6. Listener 应用程序运行时,在 Client 目录中打开一个新的命令提示符并键入 Client

如何:在配置文件中指定信道

 

由于 Listener.exe.configClient.exe.config 文件包含建立远程连接所必需的全部配置信息,因此,您只需更改配置文件中指定的信道即可更改信道,而不用重新编译应用程序。

更改配置文件中指定的信道

  1. 可以通过将 Client.exe.config 文件中的 <wellknown> 元素更改为以下形式,将信道更改为在默认情况下使用二进制序列化的 TcpChannel 对象:

    <wellknown 
       type="RemotableType, RemotableType"
       url="tcp://localhost:8989/RemotableType.rem"
    />

  2. Listener.exe.config 文件中的 <channel> 元素更改为以下形式:

    <channel ref="tcp" port="8989"/>

  3. 按照前面的执行指导重新运行该应用程序。您并不需要重新编译应用程序。

 

基本远程处理任务列表

 

.NET 远程处理是使用 .NET Framework 在应用程序域之间建立通信的几种方式之一。您必须确定应用程序需要哪些功能,并且在为分布式应用程序选择特定开发模型之前考虑可用的资源。有关指导,请参见选择 .NET 中的通信选项。下面的基本任务列表描述了生成基本 .NET 远程处理应用程序所需的基本步骤。

宿主任务

下面是发布从应用程序域之外使用的任何服务所需的步骤。

  1. 设计服务。

    1. 选择宿主应用程序域。

    2. 选择激活模型。

    3. 选择信道和端口。

    4. 决定客户端获取服务的元数据的方式。

  2. 实现宿主应用程序域。远程处理宿主可以是 Windows 服务、控制台应用程序、Windows 窗体应用程序、Internet 信息服务 (IIS) 进程或 ASP.NET 应用程序。每种应用程序的要求各不相同,因此您应该阅读描述如何生成要使用的应用程序类型的文档。有关更多信息,请参见 基于 Windows 的应用程序.NET Framework 中的 ASP.NET Web 应用程序。在宿主中,配置远程处理系统的激活模式和其他信息(如应用程序名和终结点)。如果要以编程方式配置该系统,则无需使用配置文件。如果使用配置文件,则必须通过调用 RemotingConfiguration.Configure 将该文件加载到系统中。

  3. 在宿主中,创建适当的信道并通过调用 ChannelServices.RegisterChannel 将其注册到系统。如果使用配置文件,则必须通过调用 RemotingConfiguration.Configure 将该文件加载到系统中。

  4. 若没有已发布的类,则宿主无法运行,但使用服务的实现生成宿主环境的方法取决于共享服务的公共接口的方式。

    如果要实现 XML Web 服务(使用具有默认 SOAP 序列化的 HttpChannel),则客户端可以通过三种方式获取信息:

    • 使用 Soapsuds 工具 (Soapsuds.exe) 从终结点提取信息。

    • 下载包含元数据的程序集。

    • 下载接口的源代码。

      Note注意

      在两种情况下可以使用源代码。使用服务器激活时,仅当将实现、抽象类或者接口的源代码编译为与服务器上的实际实现同名的程序集时,才可使用这些源代码。(类型标识基于类型名称和程序集名称两者。)当使用客户端激活时,必须生成一个表面上与实际服务器实现相同的类。具体而言,客户端类必须位于同名的程序集中,具有相同的类声明,并且其成员的签名必须与服务器上的相同。临时代理客户端类的实现无关紧要;如果元数据匹配,将调用远程服务器。Soapsuds.exe 为客户端生成一个临时代理类以使您不必完成此项工作。

    如果要实现其他类型的服务(例如使用 TcpChannel 对象),则客户端可以通过两种方式获取该信息:

    • 下载包含元数据的程序集。

    • 下载接口的源代码。

      Note注意

      在两种情况下可以使用源代码。使用服务器激活时,仅当将实现、抽象类或者接口的源代码编译为与服务器上的实际实现同名的程序集时,才可使用这些源代码(包括任何版本控制信息)。(类型标识基于类型名称和程序集名称信息两者。)当使用客户端激活时,必须生成一个表面上与实际服务器实现相同的类。具体而言,客户端类必须位于同名的程序集中,具有相同的类声明,并且其成员的签名必须与服务器上的相同。临时代理客户端类的实现无关紧要;如果元数据匹配,将调用远程服务器。

    无论在哪种情况下,在您自己的宿主应用程序域中对服务进行打包的方式都取决于发布其他人使用此服务所需的元数据的方式。

客户端任务

下面是使用供从应用程序域以外使用的任何服务所需的基本步骤。

  1. 设计客户端。

    1. 选择客户端应用程序域。

    2. 确定激活模式以及客户端激活 URL 或远程类型的已知对象 URL。

    3. 考虑是否需要注册信道和端口。

    4. 获取远程类型的元数据。

  2. 实现客户端应用程序域。远程处理宿主可以是 Windows 服务、控制台应用程序、Windows 窗体应用程序、Internet 信息服务 (IIS) 进程或 ASP.NET 应用程序。每种应用程序的要求各不相同,因此您应该阅读描述如何生成要使用的应用程序类型的文档。有关更多信息,请参见 Windows 应用程序.NET Framework 中的 ASP.NET Web 应用程序

  3. 用激活模式和其他类型信息(如应用程序名和对象统一资源标识符 (URI))配置客户端远程处理系统。如果要以编程方式配置该系统,则无需使用配置文件。如果使用配置文件,则必须通过调用 RemotingConfiguration.Configure 将该文件加载到系统中。

  4. 创建适当的信道并通过调用 ChannelServices.RegisterChannel 将该信道注册到系统。如果使用配置文件,则必须通过调用 RemotingConfiguration.Configure 将该文件加载到系统中。

 

 

抱歉!评论已关闭.