远程处理示例:生存期

以下代码示例说明几个生存期租约方案。CAOClient.exe 注册一个主办方(在初始租约时间后),该主办方在不同于远程类型中所指定的时间续订租约。请注意,MyClientSponsor 扩展 MarshalByRefObject 以通过对远程租约管理器的引用进行传递;如果没有这样做,而是用 SerializableAttribute 属性修饰,则此主办方将通过值传递并正常执行,但在服务器应用程序域中除外。

该应用程序可在单台计算机上运行或通过网络运行。如果要在网络上运行该应用程序,必须用远程计算机的名称替换客户端配置中的“localhost”。

此示例使用以 Visual Basic 和 C# 编写的代码。提供了 RemoteType.csCAOClient.cs,但没有通过给定的命令行进行编译。

警告

.NET 远程处理在默认情况下不进行身份验证或加密。因此,建议您在与客户端或服务器进行远程交互之前,采取任何必要的措施以确认它们的身份。因为 .NET 远程处理应用程序需要 FullTrust 权限才能执行,所以未经授权的客户端如果被授予了访问您的服务器的权限,该客户端就可以像完全受信任的客户端一样执行代码。应始终验证终结点的身份并将通信流加密,通过在 Internet 信息服务 (IIS) 中承载远程类型,或者通过生成自定义信道接收对来完成这项工作。

编译此示例

  • 在命令提示符处键入以下命令:

    vbc /t:library RemoteType.vb

    csc /r:RemoteType.dll server.cs

    vbc /r:RemoteType.dll CAOClientVB.vb

CAOClient 文件

//CAOClient.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Lifetime;

public class Client{

   public static void Main(string[] Args){
   
        // Loads the configuration file.
        RemotingConfiguration.Configure("CAOclient.exe.config");   
       
        ClientActivatedType CAObject = new ClientActivatedType();

        ILease serverLease = (ILease)RemotingServices.GetLifetimeService(CAObject);
        MyClientSponsor sponsor = new MyClientSponsor();

        // Note: If you do not pass an initial time, the first request will 
        // be taken from the LeaseTime settings specified in the 
        // server.exe.config file.
        serverLease.Register(sponsor);

        // Calls same method on each object.

        Console.WriteLine("Client-activated object: " + CAObject.RemoteMethod());

        Console.WriteLine("Press Enter to end the client application domain.");
        Console.ReadLine();
   }
}


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);
    }
}
' CAOClientVB.vb
Imports System
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Lifetime

Public Class Client
   <MTAThread()> _
   Public Shared Sub Main()
   
      ' Loads the configuration file.
      RemotingConfiguration.Configure("CAOclient.exe.config")   
       
      Dim CAObject As ClientActivatedType = New ClientActivatedType()

      Dim ServerLease As ILease = CType(RemotingServices.GetLifetimeService(CAObject), ILease)
      Dim sponsor As MyClientSponsor = New MyClientSponsor()

      ' Note: If you do not pass an initial time, the first request will be taken from 
      ' the LeaseTime settings specified in the server.exe.config file.
      ServerLease.Register(sponsor)
      
      ' Calls same method on each object.

      Console.WriteLine("Client-activated object: " & CAObject.RemoteMethod())

      Console.WriteLine("Press Enter to end the client application domain.")
      Console.ReadLine()

   End Sub 'Main
End Class 'Client


Public Class MyClientSponsor 
   Inherits MarshalByRefObject
   Implements ISponsor

   Private LastRenewal As DateTime

   Public Sub New()
      LastRenewal = DateTime.Now
   End Sub   ' MyClientSponsor

   Public Function Renewal(ByVal lease As ILease) As TimeSpan Implements ISponsor.Renewal
    
      Console.WriteLine("I've been asked to renew the lease.")
      Dim Latest As DateTime = DateTime.Now
      Console.WriteLine("Time since last renewal: " & (Latest.Subtract(LastRenewal)).ToString())
      LastRenewal = Latest
      Return TimeSpan.FromSeconds(20)

   End Function 'Renewal

End Class 'MyClientSponsor

RemoteType 文件

'RemoteType.vb
Imports System
Imports System.Runtime.Remoting.Lifetime
Imports System.Security.Principal

Public class ClientActivatedType
   Inherits MarshalByRefObject

   Public Function RemoteMethod() As String
      ' Announces to the server that the method has been called.
      Console.WriteLine("ClientActivatedType.RemoteMethod called.")

      ' Reports the client identity name.
      Return "RemoteMethod called. " & WindowsIdentity.GetCurrent().Name
   End Function  'RemoteMethod

   ' Overrides the lease settings for this object.
   Public Overrides Function InitializeLifetimeService() As Object

      Dim lease As ILease = CType(MyBase.InitializeLifetimeService(), ILease)
      
      If lease.CurrentState = LeaseState.Initial Then
         ' Normally, the initial lease time would be much longer.
         ' It is shortened here for demonstration purposes.
         lease.InitialLeaseTime = TimeSpan.FromSeconds(3)
         lease.SponsorshipTimeout = TimeSpan.FromSeconds(10)
         lease.RenewOnCallTime = TimeSpan.FromSeconds(2)
      End If

      Return lease
   End Function  'InitializeLifetimeService

End Class   'ClientActivatedType
// RemoteType.cs
using System;
using System.Runtime.Remoting.Lifetime;
using System.Security.Principal;

public class ClientActivatedType : MarshalByRefObject{


    // Overrides the lease settings for this object.
    public override Object InitializeLifetimeService(){

        ILease lease = (ILease)base.InitializeLifetimeService();
         // Normally, the initial lease time would be much longer.
         // It is shortened here for demonstration purposes.
        if (lease.CurrentState == LeaseState.Initial){
            lease.InitialLeaseTime = TimeSpan.FromSeconds(3);
            lease.SponsorshipTimeout = TimeSpan.FromSeconds(10);
            lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
        }
        return lease;
    }

    public string RemoteMethod(){

        // Announces to the server that the method has been called.
        Console.WriteLine("ClientActivatedType.RemoteMethod called.");

        // Reports the client identity name.
        return "RemoteMethod called. " + WindowsIdentity.GetCurrent().Name;

    }
}

Server.cs

using System;
using System.Runtime.Remoting;


public class Server{

   public static void Main(string[] Args){
   
      // Loads the configuration file.
        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();

   }
}

Server.exe.config

<configuration>
   <system.runtime.remoting>
      <application>
         <service>
            <activated type="ClientActivatedType, RemoteType"/>
         </service>
         <channels>
            <channel port="8080" ref="http"/>
         </channels>
      </application>
   </system.runtime.remoting>
</configuration>

CAOclient.exe.config

<configuration>
   <system.runtime.remoting>
      <application>
         <client url="https://localhost:8080">
            <activated type="ClientActivatedType, RemoteType"/>
         </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>

请参见

其他资源

远程处理示例
对象激活和生存期