.NET Remoting开发系列:(二) 对象生存周期管理

 本次议题  对象生存周期管理

 

   对于服务器对象不保留任何状态的SingleCall对象是不需要有对象租用的。只有需要保留状态的对象,无论是服务器激活的Singleton 还是客户端激活的对象才需要对象租用。

 

 租约

 生命周期

 发起人(Sponsor) 

下面是NET Remoting 为管理远程对象的生存期管理的架构:

ILease 接口定义了很多用于管理对象生存期的属性:

  • InitialLeaseTime。确定租用最初的有效期。
  • RenewOnCallTime。在每个方法调用后,更新此时间单元的租用。
  • SponsorshipTimeout。负责人通知租用过期后,Remoting 要等待的时间。
  • CurrentLeaseTime。距租用到期的时间(只读)。
续约的方法有3种:
1)隐式续约:当客户调用远程对象上的方法时,租约的隐式续借会自动进行。
2)显示续约:通过ILease接口的Renew()方法完成。通过调用透明代理对象的GetLifeService()方法,就可以使用ILease接口。
3)发起租约:客户可以创建一个实现ISponsor接口的发起者,并使用ILease接口的Register()方法在租约服务中注册这个发起者。发起者定义租约延长的时间。当租约到期时,发起者就要求延长租约时间。如果长期租约服务器上的远程对象,可以使用这个发起租约机制。

 

开发Remoting三步走

1、 远程对象: 

    建立类库项目:General 

public   class  ClientActivatedType : MarshalByRefObject
{
    
public   override  Object InitializeLifetimeService()
    {
        
// ILease接口定义了有关生命周期的属性,均为TimeSpan值
        ILease lease  =  (ILease) base .InitializeLifetimeService();
        
// 该租约状态。
         if  (lease.CurrentState  ==  LeaseState.Initial)
        {
            
// 初始化有效时间,默认值为300秒,如果为0,表示永不过期;
            lease.InitialLeaseTime  =  TimeSpan.FromSeconds( 3 ); //这个3改成0,永远不过期。
            
// 超时值,通知Sponsor(发起人)租用过期后,Remoting会等待的时间,默认值为120秒;
            lease.SponsorshipTimeout  =  TimeSpan.FromSeconds( 10 );
            
// 调用远程对象一个方法时的租用更新时间,默认值为120秒;
            lease.RenewOnCallTime  =  TimeSpan.FromSeconds( 2 );
        }
        
return  lease;
    }
    
public   string  RemoteMethod()
    {
        Console.WriteLine(
" ClientActivatedType.RemoteMethod called. " );
        
return   " RemoteMethod called.  "   +  WindowsIdentity.GetCurrent().Name;
    }

} 

2、服务端建立控制台项目:Server

 

public   class  Server
{
    
public   static   void  Main( string [] Args)
    {
        
// 读取配置文件
        RemotingConfiguration.Configure( " server.exe.config " );

        Console.WriteLine(
" The server is listening. Press Enter to exit.... " );
        Console.ReadLine();

        Console.WriteLine(
" Recycling memory... " );
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}

 

服务器端配置文件  App.config 

 

< configuration >
    
< system.runtime.remoting >
        
< application >
            
< service >
                
< activated  type ="ClientActivatedType, General" />
            
</ service >
            
< channels >
                
< channel  port ="8080"  ref ="http" >
                    
< serverProviders >
                        
< formatter  ref ="soap"  typeFilterLevel ="Full" />
                        
< formatter  ref ="binary"  typeFilterLevel ="Full" />
                    
</ serverProviders >
                
</ channel >
            
</ channels >
        
</ application >
    
</ system.runtime.remoting >
</ configuration >

(1) 首先建立如上的监控处理类;

(2) 注册通道:

TcpChannel channel = new TcpChannel(8080);

ChannelServices.RegisterChannel(channel);

(3) 设置租用管理器的初始租用时间为无限:

LifetimeServices.LeaseTime = TimeSpan.Zero;

(4) 创建该跟踪处理类的实例,并注册跟踪服务:

TrackingServices.RegisterTrackingHandler(new MyTracking());

(5) 编组两个远程对象:

ServerAS.AppService1 service1 = new ServerAS1.AppService1();

ObjRef objRef1 = RemotingServices.Marshal((MarshalByRefObject)service1,"AppService1");

ServerAS.AppService2 service2 = new ServerAS1.AppService2();

ObjRef objRef2 = RemotingServices.Marshal((MarshalByRefObject)service2,"AppService2");

(6) 使服务器端保持运行:

Console.WriteLine("Remoting服务启动,按退出..."); 

Console.ReadLine();

 

3、客户端:建立控制台项目:Client

 

public   class  Client
{
    
public   static   void  Main( string [] Args)
    {
        RemotingConfiguration.Configure(
" client.exe.config " );

        ClientActivatedType CAObject 
=   new  ClientActivatedType();
        
// 租用
        ILease serverLease  =  (ILease)RemotingServices.GetLifetimeService(CAObject);
        
// 发起人(Sponsor) 续租时间
        MyClientSponsor sponsor  =   new  MyClientSponsor();
        
//  Register()或Renewal()方法来注册远程对象或延长生命周期
        serverLease.Register(sponsor);

        Console.WriteLine(
" Client-activated object:  "   +  CAObject.RemoteMethod());
        Console.WriteLine(
" Press Enter to end the client application domain. " );
        Console.ReadLine();
    }
}
// 发起人(Sponsor)
public   class  MyClientSponsor : MarshalByRefObject, ISponsor
{
    
private  DateTime lastRenewal;
    
public  MyClientSponsor()
    {
        lastRenewal 
=  DateTime.Now;
    }
    
public  TimeSpan Renewal(ILease lease)
    {
        Console.WriteLine(
" I've been asked to renew the lease. " );
        Console.WriteLine(
" Time since last renewal: "   +  (DateTime.Now  -  lastRenewal).ToString());
        lastRenewal 
=  DateTime.Now;
        
return  TimeSpan.FromSeconds( 20 );
    }
}

 

 客户端配置文件  App.config 

< configuration >
    
< system.runtime.remoting >
        
< application >
            
< client  url ="http://localhost:8080" >
                
< activated  type ="ClientActivatedType, General" />
            
</ client >
            
< channels >
                
< channel  ref ="http"  port ="0" >
                    
< serverProviders >
                        
< formatter  ref ="soap"  typeFilterLevel ="Full" />
                        
< formatter  ref ="binary"  typeFilterLevel ="Full" />
                    
</ serverProviders >
                
</ channel >
            
</ channels >
        
</ application >
    
</ system.runtime.remoting >

</ configuration>


    通过Marshal编组的对象要受到租用的生命周期所控制。注意对象被Disconnect,并不是指这个对象被GC回收,而是指这个对象保存在通道的相关代理信息被断开了,而对象本身仍然在服务器端存在。

 

    所以我们通过Remoting提供服务,应根据实际情况指定远程对象的生命周期,如果不指定,则为Remoting默认的设定。要让所有的远程对象永久有效,可以通过配置文件或租用管理器将初始有效时间设为0。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值