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.
Caution |
---|
.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. REDMOND\migree
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
Type the following commands at the command prompt:
[C#]
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
[Visual Basic]
RemoteType
[C#]
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;
}
}
}
[Visual Basic]
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>