添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

服务器激活

服务器激活的对象是生存期直接受服务器直接控制的对象。仅当客户端对对象进行方法调用时,服务器应用程序域才会创建这些对象,而不是当客户端调用 new Activator.GetObject 的时候。客户端请求服务器激活类型的实例时,会在客户端应用程序域中创建一个代理。服务器激活类型只允许使用默认构造器。如果想使用特定的采用参数的构造器创建实例的类型,可以使用客户端激活,也可以动态发布特定实例。

服务器激活的对象有两种激活模式: Singleton SingleCall ,这两种模式又叫已知对象,由枚举类型: WellKnownObjectMode 来标识。

Singleton 类型在任一时刻只有一个实例。所有的客户端请求都将由这个实例提供服务。如果不存在实例,则服务器创建一个,且所有的后来的客户端请求都将由这个实例提供服务。对于单件类型,会关联到默认的生存期。

SingleCall 类型针对每个客户端请求创建一个实例。下一个方法调用将由其他服务器实例提供服务,即使在系统尚未回收前一个实例的引用的情况下也是这样。

RemotingConfiguration

方法 RegisterWellKnownServiceType 将服务器上的对象类型注册为已知类型

public static void RegisterWellKnownServiceType(

Type type,

string objectUri,

WellKnownObjectMode mode)

所有知道已注册已知对象的 URI 的客户都可以获取该对象的代理,方法是:用 ChannelServices 注册信道,然后调用 new Activator.GetObject 方法来激活对象。

· 当用 new 来激活对象时,须先要使用 RegisterWellKnownClientType 方法在客户端注册该已知对象类型。调用 RegisterWellKonwnClientType 方法向远程处理基础结构提供远程对象的位置,使 new 关键字可以创建它。

· 当用 Activator.GetObject 方法来激活已知对象时,须将对象的 URL 作为参数提供给该方法,所以在这种情况下,不用预先在客户端注册。

当调用到达服务器后,系统从消息中提取 URI ,检查远程处理表以定位与该 URI 匹配的对象的引用,然后实例化该对象,将方法调用转发给该对象。如果是 SingleCall ,则在方法调用完成后,该对象被销毁。为每个方法创建对象的一个新实例。

Activator.GetObject new 的区别是: Activator.GetObject 可以指定 URL 作为参数, new 的时候是从配置中获取 URL

1 )通过 Actovator.GetObject 方法来获取代理

Activator 类位于 System 下。它包含一些方法,用于在本地或从远程创建对象类型,或获取对现有远程对象的引用。其中 GetObject 这个方法有 2 个重载,方法的意义是:为已知对象或 XML Web services 创建一个代理。

GetObject(Type, String) 为指定类型和 URL 所指示的已知对象创建一个代理。

GetObject(Type, String, Object) 为指定类型、 URL 和通道数据所指示的已知对象创建一个代理。

以第一个 2 个参数的方法为例子:第一个参数 Type ,是在服务端注册为已知类型的类型,第二个参数是已知对象的 URL

HttpChannel _channel = new HttpChannel (10001);

ChannelServices .RegisterChannel(_channel, false );

Console .WriteLine( "http 通道 remoting 服务开始 ……" );

RemotingConfiguration .RegisterWellKnownServiceType(

typeof ( selfRemoteObject ), "selfRemoteObject" ,

WellKnownObjectMode .Singleton);

public void TestService()

selfRemoteObject app =

( selfRemoteObject ) Activator .GetObject(

typeof ( selfRemoteObject ),

"http://localhost:10001/selfRemoteObject" );

Assert .AreEqual(13,app.Plus(3, 10));

2 )通过 new 来创建代理

当用 new 来激活对象时,先要使用 RegisterWellKnownClientType 方法在客户端注册该已知对象类型。然后使 new 关键字可以创建它。

服务端还是( 1 )中的服务端

public void TestServiceNew()

RemotingConfiguration .RegisterWellKnownClientType(

typeof ( selfRemoteObject ),

"http://localhost:10001/selfRemoteObject" );

selfRemoteObject app = new selfRemoteObject ();

Assert .AreEqual(13, app.Plus(3, 10));

以上两种方法在创建代理后,调用方法时,服务端会管理已知类型对象的创建工作,这种生成对象是按默认的构造器(无参)来进行。

客户端激活

客户端激活的对象由调用应用程序域控制其生存期的对象,这种情况与应用程序域控制本地对象生存期一样。

创建客户端激活对象时,客户端将调用服务器。服务器实例化远程对象,并将对象引用返回给客户端。客户端使用这个引用创建远程对象的代理。每当客户端创建客户端激活对象的实例时,都会收到与远程对象的特定服务器实例进行通信的代理,直至其租约过期,内存被回收为止。

采用客户端激活方式的步骤:

· 要在服务器上创建客户端激活的对象的实例,要知道它的 Type

· 使用 RegisterActivatedServiceType 方法在服务端注册它。

客户端步骤:

· 客户端先向 ChannelServices 注册一个通道,

· 通过调用 new Activator.CreateInstance 激活对象。

创建客户端激活类型实例的两种方式:

· new 来进行

· Activator.CreateInstance 的调用中传递远程对象

先准备服务端:

HttpChannel _channel = new HttpChannel (10001);

ChannelServices .RegisterChannel(_channel, false );

Console .WriteLine( "http 通道 remoting 服务开始 ……" );

RemotingConfiguration .ApplicationName = "selfRemoteObject" ;

RemotingConfiguration .RegisterActivatedServiceType

( typeof ( selfRemoteObject ));

Console .Read();

服务端要通过 RegisterActivatedServiceType 方法来注册类型,且先要设定 ApplicationName ,这个就相当于 URL

1 )以 new 来进行

public void TestClientNew()

HttpChannel _channel = new HttpChannel ();

ChannelServices .RegisterChannel(_channel, false );

RemotingConfiguration .RegisterActivatedClientType

typeof ( selfRemoteObject ),

"http://localhost:10001/selfRemoteObject" );

selfRemoteObject app1 = new selfRemoteObject ();

Assert .AreEqual(10, app1.Plus(1, 9));

通过 new 来激活客户端对象类型,先使用 RegisterActivatedClientType 方法在客户端注册该对象类型,然后 new 就可以了。

2 Activator.CreateInstance

如果用 CreateInstance ,则要提供远程应用程序的 URL 作为参数,不用在客户端注册类型。如果要用到 URL 做参数,则 URL 要封装在 UrlAttribute 类实例中。

public void TestClientInstance()

HttpChannel _channel = new HttpChannel ();

ChannelServices .RegisterChannel(_channel, false );

object [] url={ new UrlAttribute

( "http://localhost:10001/selfRemoteObject" )};

selfRemoteObject app1 =

( selfRemoteObject ) Activator

.CreateInstance( typeof ( selfRemoteObject ), null , url);

Assert .AreEqual(10, app1.Plus(1, 9));

客户端激活方式可以使用带参构造器来创建远程对象实例。

修改远程对象,添加一属性一个带参构造器:

public int Unid { get ; set ; }

public selfRemoteObject() { }

public selfRemoteObject( int iUnid)

Unid = iUnid;

添加了带参构造器,要显示声明默认的无参构造器。

通过 new 方法来创建对象实例。

selfRemoteObject app1 = new selfRemoteObject ();

Assert .AreEqual(0, app1.Unid);

selfRemoteObject app2 = new selfRemoteObject (10);

Assert .AreEqual(10, app2.Unid);

激活方式,是远程对象实例创建的的管理方式。服务器端激活就是由服务端来管理远程对象的创建,在这种方式下,当客户端调用方法时,才创建实例;客户端激活由客户端来管理远程对象的创建,在这种方式下,当客户端发出调用就创建实例。

RemotingConfiguration 类的类型注册方法:

RegisterActivatedClientType 将客户端上的对象 Type 注册为可在服务器上激活的类型。

RegisterActivatedServiceType 将服务端上的对象 Type 注册为可根据请求从客户端激活的类型。

RegisterWellKnownClientType 将客户端上的对象 Type 注册为已知类型( 单个调用 ”(singlecall) singleton )。

RegisterWellKnownServiceType 将服务端上的对象 Type 注册为已知类型( 单个调用 ”(singlecall) singleton )。

RemotingServices.Disconnect 这个方法用于阻止对象通过注册的远程处理信道再接收消息。它的参数须是实例化的对象(要关闭的),服务端注册类型要通过 Marshal 方法来进行:

HttpChannel _channel = new HttpChannel (10001);

ChannelServices .RegisterChannel(_channel, false );

Console .WriteLine( "http 通道 remoting 服务开始 ……" );

selfRemoteObject obj= new selfRemoteObject ();

RemotingServices .Marshal(obj, "selfRemoteObject" );

断开时,通过 Disconnect 方法:

RemotingServices .Disconnect(obj);