当前位置:编程技术网 > 技术文章 > 通信及分布式开发 > 文章详细内容

Dotnet中 Remoting技术 简明扼要的介绍 2 - 3

 

六、激活模式 Activation  requests

(一)   服务器端2

1.         SingleCall(单调用)

对于客户端的每一个代理类的函数调用都产生一个组件服务对象,当函数调用结束后,对象销毁。

Web服务器实际就是这种SingleCall方式)

 

对于每一个客户端的函数调用都会产生一个服务组件对象。此对象的生命周期是该客户端函数范围,也就是说调用结束后就销毁该对象。

使用情形:

       适合没有状态的应用程序。  比如 一个客户代理有两个方法都操作同一个变量 i 首先把 i的值改成100 然后用另一个方法去取值, 得到的还是默认值,因为2个方法调用的 不同对象。

       负载平衡性比较好, 用到创建,不用时马上销毁。

      

2.         Singleton(单件)

使用只有一个 远程范围对象 实例,当应用程序启动或者第一此调用时候创建。 任何时候就只有1个对象在提供服务。 这个时候就可以保存状态信息。

 

使用情形:

       对象构造过程非常耗时。

       需要保存程序执行状态的情况下。

       完全编程方式编写宿主:

using System;using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Http;

using System.Runtime.Remoting.Channels.Tcp;

//一个控制台的宿主应用程序。

class RemotingHost{

    static void Main(string[] args)    {

        //提供的远程组件的服务的名字。

        RemotingConfiguration.ApplicationName = "WiseOwlMathService";

 

        WellKnownServiceTypeEntry WKSTE = new WellKnownServiceTypeEntry(

            typeof(WiseOwl.Calculator),     //服务对象

            "SharedCalc",                   //客户端请求名,也就是请求入口

            WellKnownObjectMode.Singleton   //激活模式(单调用SingleCall、单件Singleton

            );

        RemotingConfiguration.RegisterWellKnownServiceType(WKSTE);

 

        //HTTP9000端口TCP4242端口监听请求,客户端可以通过种方式请求。

        ChannelServices.RegisterChannel(new HttpChannel(9000));

        ChannelServices.RegisterChannel(new TcpChannel(4242));

 

        Console.ReadLine();}}

/* 客户端调用方式

 * ProtocolScheme://ComputerName:Port/PossibleApplicationName/ObjectUri

 *  PossibleApplicationName - 此处应该填:"WiseOwlMathService"

 *  ObjectUri               - 此处应该填:"SharedCalc"

 *

 * 如果是以IIS作为宿主,则PossibleApplicationName为虚拟目录名,ObjectUri必须以.rem/.soap结尾 */

配置文件方式控制宿主:

fileName : testServerHost.exe.config

<configuration>

  <system.runtime.remoting>

    <!--服务名-->

    <application name="WiseOwlMathService">

      <service>

        <!--

        wellknown 译 “众所周知”

        也就是服务器激活模式,因为服务器控制一切,所有的调用都要取决于服务器。

       

        此处配置为同时提供2种服务器激活模式。

        可以在客户端请求的时候提供 不同的URI

                            来使用 不同的激活模式。

        -->

        <wellknown mode="SingleCall" type="WiseOwl.Calculator,MathObjects" objectUri = "EphemeralCalc" />

        <wellknown mode="Singleton" type="WiseOwl.Calculator,MathObjects" objectUri = "SharedCalc" />

      </service>

      <channels>

        <channel port="9000" ref="http" />

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

      </channels>

    </application>

  </system.runtime.remoting>

</configuration>

 

fileName : testServerHost.exe

using System;

using System.Reflection;

using System.Runtime.Remoting;

class RemotingHost {

    static void Main(string[] args)    {

        String s = Assembly.GetExecutingAssembly().Location;

        RemotingConfiguration.Configure(s + ".config");

        Console.ReadLine();

    } }

 

(二)   客户端1

1.         Client activated object (CAO)

提供多种 组件服务器对象生命周期 管理方式:

1 创建客户代理类的实例 就产生对应的 服务器 组件服务器对象, 客户代理类销毁,服务器销毁。

2 租借机制, 创建客户端代理类实例并不是创建,而是向服务器租借对象。到期如果不续租,就销毁了。(可以防止客户端忘记销毁代理类实例所引发服务器资源浪费)

       完全编程方式:

using System;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Http;

using System.Runtime.Remoting.Channels.Tcp;

class RemotingHost{

    static void Main(string[] args){

        RemotingConfiguration.ApplicationName = "WiseOwlMathService";

 

        //ActivatedServiceTypeEntry : 表示客户端激活类型

        //服务器端激活对应为WellKnownServiceTypeEntry

        ActivatedServiceTypeEntry ASTE = new ActivatedServiceTypeEntry(typeof(WiseOwl.Calculator));

 

        //RegisterActivatedServiceType()方法表示注册一个客户端激活的服务,

        //服务器端激活类型的服务注册对应的方法是:RegisterWellKnownServiceType()

        RemotingConfiguration.RegisterActivatedServiceType(ASTE);

 

        ChannelServices.RegisterChannel(new HttpChannel(9000));

        ChannelServices.RegisterChannel(new TcpChannel(4242));

 

        Console.ReadLine();}}

/* 客户端调用方式(无URI

 *  ProtocolScheme://ComputerName:Port/PossibleApplicationName

 */

使用配置文件方式:

fileName : testServerHost.exe.config

<configuration>

  <system.runtime.remoting>

    <application name="WiseOwlMathService">

      <service>

        <!--

        activated 客户端激活

        wellknown 服务器端激活

        -->

        <activated type="WiseOwl.Calculator,MathObjects" />

      </service>

      <channels>

        <channel port="9000" ref="http" />

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

      </channels>

    </application>

  </system.runtime.remoting>

</configuration>

fileName : testServerHost.exe   //服务器端激活和客户端激活,完全一样

using System;

using System.Reflection;

using System.Runtime.Remoting;

class RemotingHost {

    static void Main(string[] args)    {

        String s = Assembly.GetExecutingAssembly().Location;

        RemotingConfiguration.Configure(s + ".config");

        Console.ReadLine();

    } }

 

七、Remoting clients  远程处理的客户端编写。

(一)  调用 服务器端激活 的远程对象

1.         可以使用Activator.GetObject(类型, URL; 获取远程代理类的对象。

using System;using System.Runtime.Remoting;using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Http;using System.Runtime.Remoting.Channels.Tcp;

class RemotingClient{

    static void Main(){

        //客户通过http通道和服务器联系

        //此处new HttpChannel()不需要写端口号,因为Machine.config中已经设置的有默认端口。

        ChannelServices.RegisterChannel(new HttpChannel());

 

        // Connect to a Well-known object    

        string uriWKO = "http://localhost:9000/WiseOwlMathService/SharedCalc";

        object o = Activator.GetObject(typeof(WiseOwl.Calculator), uriWKO);

 

        // Use the Calculator  

        WiseOwl.Calculator c;

        c = o as WiseOwl.Calculator;

 

        c.Add(21);

}}

2.         也可以使用New 如果传递给客户端的元数据不是接口组件,而是整个服务组件,则可以new,否则只能用上面的方法

(二)  调用 客户端激活 的远程对象

1.         可以使用Activator.CreateInstance()方法。获取远程代理类的对象。

using System;using System.Runtime.Remoting;using System.Runtime.Remoting.Activation;

using System.Runtime.Remoting.Channels;using System.Runtime.Remoting.Channels.Http;

using System.Runtime.Remoting.Channels.Tcp;

class RemotingClient{

     static void Main() {

         //客户通过http通道和服务器联系 

         ChannelServices.RegisterChannel(new TcpChannel());

 

         // Connect to a Well-known object    

         string url = "tcp://localhost:4242/WiseOwlMathService";       

         object[] activationAttributes = new object[]{new UrlAttribute(url)};

         object o = Activator.CreateInstance(typeof(WiseOwl.Calculator),null,activationAttributes);

 

         // Use the Calculator  

         WiseOwl.Calculator c;

         c = o as WiseOwl.Calculator;

         c.Add(21); 

     }}

2.         也可以使用New 如果传递给客户端的元数据不是接口组件,而是整个服务组件,则可以new,否则只能用上面的方法

 

八、客户端调用也可以使用 配置文件

fileName : testServerCall.exe.config

<configuration>

  <system.runtime.remoting>

    <application name="WiseOwlMathService">

      <client url = "http://localhost:9000/WiseOwlMathService" displayName = "WiseOwlMathService">

        <!--客户端激活-->

        <activated type = "WiseOwl.Calculator,MathObjects"/>

        <!--服务器端激活-->

        <wellknown type = "WiseOwl.BadCalculator,MathObjects" url="http://localhost:9000/WiseOwlMathService/BadCalc"/>

      </client>

    </application>

  </system.runtime.remoting>

</configuration>

fileName : testServerCall.exe

using System;using System.Runtime.Remoting;using System.Runtime.Remoting.Activation;

using System.Runtime.Remoting.Channels;using System.Runtime.Remoting.Channels.Http;

using System.Runtime.Remoting.Channels.Tcp;

class RemotingClient{

     static void Main() {

         string s = System.Reflection.Assembly.GetExecutingAssembly().Location;

        System.Runtime.Remoting.RemotingConfiguration.Configure(s + ".config");

         //使用配置文件且读入配置后,就可以直接new对象。new的前提是客户端有完整的服务元数据,也就是不是接口。当然也应该还是可以不new的。这个地方虽然是new,但还是获得的远程对象。

         WiseOwl.Calculator c = new WiseOwl.Calculator();

         c.Add(21);

 

         WiseOwl.BadCalculator b = new WiseOwl.BadCalculator();

         b.Add(21);             }}

作者|来源:原创(17fx.net)发表于:2009-3-24 23:01:00