深度管理Remote Objects的生存期

来源:百度文库 编辑:神马文学网 时间:2024/03/29 23:30:57

Manage the lifetime of remote objects in depth

 

在《灵活管理Remote Objects生存期(lifetime)》一文中,提及了Remote Objects生存期管理的一些基本方面,已经可以满足一般基于.Net Remoting的应用。如果你觉得那些关于Remote Objects的生存期管理机制还不满足需求,则可以考虑实现Client端或Server端的Sponser对象。

 

这里将深入讨论Remote Objects生存期管理的Sponsor机制,Sponsorship is confusing, but also powful。(MSDN译:Sponsor – 主办方, Lease - 生存期租约,LeaseManager -租约管理器)

 

当Remote Object创建时,Sponsor向Remote Object提出注册。当Remote Object的生存期TTL要结束时,LeaseManager负责与注册的Sponsor联系。如果Sponsor返回一个时间段TimeSpan,通知Remote Object的生存期延长指定时间段;如果Sponsor返回TimeSpan.Zero,则Remote Object结束其生存状态。

 

Sponsor对象本身是一个MarshalByRefObject对象,并且实现ISponsor接口。另外,Sponsor对象可以存放在Remote Object所在的Server端、其他的Server端、或者是Client端application,但是必须满足.Net Remoting Framework可以访问到Sponsor对象。(注意:如果Sponsor存放在Client端,并且Client在firewall后面,Server端的LeaseManager就无法访问到Sponsor了。)

 

一个典型的Sponsor对象如下:

public class MySponsor: MarshalByRefObject, ISponsor

{

   private bool NeedsRenewal()

   {

 

      // check some internal conditions

      return true;

   }

 

   public TimeSpan Renewal(System.Runtime.Remoting.Lifetime.ILease lease)

   {

      if (NeedsRenewal())

      {

         return TimeSpan.FromMinutes(5);

      }

      else

      {

         return TimeSpan.Zero;

      }

   }

}

 

一般而言,对于CAO(客户端激活对象)对象,Sponsor对象位于Client端。对于SAO(服务端激活对象)则相反。下面分别了解两种情况的Sponsor对象:

 

1ClientSponsor

为了让Remote Objects能够与Client端的Sponsor打交道,需要在Client配置文件中Channel设置port属性。如果没有这个属性,Channel就无法接受来自Server的回调。

Port=”0”表示允许.Net Remoting Framework选择Client端任一空闲的port。

另外,我们知道在调用CAO远程对象时,还需要为配置文件的client项指定url属性。

注册Sponsor对象,避免Remote Objects过早的释放(Client端application部分示例代码):

string filename = "client.exe.config";

RemotingConfiguration.Configure(filename);

// 实例化CAO对象

SomeCAO cao = new SomeCAO();

// Get an object’s LifetimeService, which will be an ILease object.

ILease le = (ILease) cao.GetLifetimeService();

MySponsor sponsor = new MySponsor();

// Register the sponsor with the server object’s lease

le.Register(sponsor);

…调用Remote method或处理其他事情

// Unresister the sponsor with the server objects

le.Unregister(sponsor);

 

当application准备让server释放CAO对象实例时,application通过告诉sponsor对象停止更新CAO对象实例的TTL。通常情况下,application通过调用Lease.Unregister()方法来取消sponsor对象的注册,这样CAO对象实例就不会与sponsor联系了。

 

注意:当你决定使用client端的sponsor时,需要确保server可以访问到client,这样client就不能在firewall或proxy后面。

 

2ServerSponsor

Server端的Sponsor对象一般用来管理SAO对象的生存期,在实现方式上基本与Client端Sponsor对象一致。

但是,需要注意的是Remote sponsor对象也是MarshalByRefObject对象,因此也和Remote Objects一样,需要管理其生存期。一般情况下,我们需要Server端sponsor对象与Client端application保持相同的生存期,当Client端application关闭时,要求尽快释放Server端sponsor对象。

Ingo Rammer《Advanced .Net Remoting》中提出了一种方案来实现Server端sponsor对象。

(1) 通过Client端后台线程EnsureKeepAlive对象不断调用sponsor.KeepAlive()方法,确保sponsor对象存活。

(2) 为了防止Client端application意外关闭或出现网络连接故障,无法正确调用Unregister()方法来取消注册,造成Remote Objects和sponsor对象一直存活。为了解决这一潜在问题,在sponsor.KeepAlive()方法中记录更新lastKeepAlive的时间,并在sponsor.Renewal()方法判断renew请求是否在指定的时间间隔内,如果是,则返回指定的TTL时间段,反之,则返回TimeSpan.Zero。


注意Server和Client端主要类如上图所示,Source Code请参考《Advance .Net Remoting》Chapter 6(Remote Object和sponsor可以为CAO或SAO对象)。

 

 

Reference:

1. Ingo Rammer, Advanced .Net Remoting.

2. Rickie, 《灵活管理Remote Objects生存期(lifetime)