Пример удаленного взаимодействия. Время существования
Этот раздел относится к технологии прежних версий, которая сохраняется для обеспечения обратной совместимости с существующими приложениями и не рекомендуется для разработки новых приложений. Сейчас распределенные приложения следует создавать с помощью Windows Communication Foundation (WCF).
В следующем примере кода показано несколько случаев аренды времени существования. Программа Client.exe
регистрирует спонсора, который (после времени начальной аренды) продлевает аренду промежутка времени TimeSpan, отличного от промежутка, указанного в методе ClientActivatedType.InitializeLifetimeService()
. Следует помнить, что объект MyClientSponsor
расширяет объект MarshalByRefObject таким образом, что его можно по ссылке передавать диспетчеру аренды (в домене приложения Server.exe
). Это приложение выполняется на одном компьютере или в сети. Если требуется запускать это приложение в сети, необходимо в конфигурации клиента заменить "localhost" на имя удаленного компьютера.
Внимание! |
---|
По умолчанию при удаленном взаимодействии .NET Framework проверка подлинности и шифрование не выполняются. Поэтому рекомендуется принять все необходимые меры для проверки удостоверений клиентов и серверов до удаленного взаимодействия с ними. Поскольку для запуска приложений, использующих удаленное взаимодействие .NET Framework, требуются разрешения FullTrust, если неавторизованный клиент получит доступ к серверу, клиент сможет запускать код так, как если бы он был полностью доверенным. Всегда выполняйте проверку подлинности конечных точек и шифрование потоков взаимодействия, либо разместив типы, поддерживающие удаленное взаимодействие, в службах IIS, либо создав пользовательскую пару приемников каналов для выполнения этих задач. |
Запустите файл Server.exe, затем Client.exe, и появится результат следующего вида.
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
Компиляция этого образца
В командной строке введите следующие команды:
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
Сервер
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>
Клиент
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>
См. также
Другие ресурсы
Примеры удаленного взаимодействия
Активация и время существования объектов