Remoting Example: Lifetimes

This topic is specific to a legacy technology that is retained for backward compatibility with existing applications and is not recommended for new development. Distributed applications should now be developed using the  Windows Communication Foundation (WCF).

The following code example demonstrates several of the lifetime-lease scenarios. Client.exe registers a sponsor that (after the initial lease time) renews the lease for a TimeSpan different from that specified in the ClientActivatedType.InitializeLifetimeService(). Be aware that the MyClientSponsor extends MarshalByRefObject so that it can be passed by reference to the lease manager (in the Server.exe Application Domain). This application runs on a single computer or across a network. If you want to run this application over a network, you must replace "localhost" in the client configuration with the name of the remote computer.

6tkeax11.Caution(en-us,VS.100).gifCaution:
.NET Remoting does not perform authentication or encryption by default. Therefore, it is recommended that you take all necessary steps to verify the identity of clients or servers before interacting with them remotely. Because .NET Remoting applications require FullTrust permissions to execute, if a unauthorized client were granted access on your server, the client could execute code as though it were fully trusted. Always authenticate your endpoints and encrypt the communication streams, either by hosting your remoted types in Internet Information Services (IIS) or by building a custom channel sink pair to do this work.

Run Server.exe and then Client.exe you should see output like the following:

Server.exe:

C:\projects\Lifetime\Server\bin>server

The server is listening. Press Enter to exit....

ClientActivatedType.RemoteMethod called.

Client.exe:

C:\projects\Lifetime\Client\bin>client

Client-activated object: RemoteMethod called. MyDomain\SomeUser

Press Enter to end the client application domain.

I've been asked to renew the lease.

Time since last renewal:00:00:09.9432506

I've been asked to renew the lease.

Time since last renewal:00:00:29.9237760

To compile this sample

  1. Type the following commands at the command prompt:

    csc /t:library RemoteType.cs
    csc /r:System.Runtime.Remoting.dll /r:RemoteType.dll server.cs
    csc /r:System.Runtime.Remoting.dll /r:RemoteType.dll client.cs
    
    vbc /t:library RemoteType.vb
    vbc /r:System.Runtime.Remoting.dll /r:RemoteType.dll server.vb
    vbc /r:System.Runtime.Remoting.dll /r:RemoteType.dll client.vb
    

RemoteType

using System;
using System.Runtime.Remoting.Lifetime;
using System.Security.Principal;

namespace RemoteType
{
    public class ClientActivatedType : MarshalByRefObject
    {
        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;
        }
    }
}
Imports System
Imports System.Runtime.Remoting.Lifetime
Imports System.Security.Principal

Namespace RemoteType
Public Class ClientActivatedType
    Inherits MarshalByRefObject

    Public Overrides Function InitializeLifetimeService() As Object
        Dim lease As ILease = MyBase.InitializeLifetimeService()

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

    Public Function RemoteMethod() As String
        Console.WriteLine("ClientActivatedType.RemoteMethod called.")

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

End Class
End Namespace

Server

using System;
using System.Runtime.Remoting;

namespace Server
{
    class Program
    {
        static void Main(string[] args)
        {
            RemotingConfiguration.Configure("Server.exe.config", false);
            Console.WriteLine("The server is listening. Press Enter to exit....");
            Console.ReadLine();
        }
    }
}
Imports System
Imports System.Runtime.Remoting

Class Program
    Shared Sub Main()
        RemotingConfiguration.Configure("Server.exe.config", False)
        Console.WriteLine("The server is listening. Press Enter to exit....")
        Console.ReadLine()
    End Sub
End Class

Server.exe.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.runtime.remoting>
    <application>
      <channels>
        <channel ref="tcp" port="1234">
          <serverProviders>
            <formatter ref="binary" typeFilterLevel="Full"/>
          </serverProviders>
          <clientProviders>
            <formatter ref="binary"/>
          </clientProviders>
        </channel>
      </channels>
      <service>
        <activated type="RemoteType.ClientActivatedType, RemoteType" />
      </service>
    </application>
  </system.runtime.remoting>
</configuration>

Client

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Lifetime;
using RemoteType;

class Client
{
    static void Main(string[] args)
    {
        RemotingConfiguration.Configure("Client.exe.config",false);
        ClientActivatedType obj = new ClientActivatedType();

        ILease lease = (ILease)obj.GetLifetimeService();
        MyClientSponsor sponsor = new MyClientSponsor();
        lease.Register(sponsor);

        Console.WriteLine("Client-activated object: " + obj.RemoteMethod());
        Console.WriteLine("Press Enter to end the client application domain.");
        Console.ReadLine();
    }
}

public class MyClientSponsor : MarshalByRefObject, ISponsor
{
    private DateTime lastRenewal;

    public MyClientSponsor()
    {
        Console.WriteLine("MyClientSponsor.ctor called");
        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);
    }
}
Imports System
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Lifetime
Imports RemoteType

Class Client

    Shared Sub Main()
        RemotingConfiguration.Configure("Client.exe.config", False)
        Dim obj As ClientActivatedType = New ClientActivatedType()

        Dim lease As ILease = CType(obj.GetLifetimeService(), ILease)
        Dim sponsor As MyClientSponsor = New MyClientSponsor()
        lease.Register(sponsor)

        Console.WriteLine("Client-activated object: " + obj.RemoteMethod())
        Console.WriteLine("Press Enter to end the client application domain.")
        Console.ReadLine()
    End Sub

End Class

Public Class MyClientSponsor
    Inherits MarshalByRefObject
    Implements ISponsor

    Dim lastRenewal As DateTime

    Public Sub New()
        lastRenewal = DateTime.Now
    End Sub

    Public Function Renewal(ByVal lease As System.Runtime.Remoting.Lifetime.ILease) As System.TimeSpan Implements System.Runtime.Remoting.Lifetime.ISponsor.Renewal
        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)
    End Function
End Class

Client.exe.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.runtime.remoting>
    <application>
      <channels>
        <channel ref="tcp" port="0">
          <clientProviders>
            <formatter ref="binary"/>
          </clientProviders>
          <serverProviders>
            <formatter ref="binary" typeFilterLevel="Full"/>
          </serverProviders>
        </channel>
      </channels>
      <client url="tcp://localhost:1234">
        <activated type="RemoteType.ClientActivatedType, RemoteType" />
      </client>
    </application>
  </system.runtime.remoting>
</configuration>

See Also

Other Resources

Remoting Examples
Object Activation and Lifetimes