远程处理示例:生存期
以下代码示例说明几个生存期租约方案。CAOClient.exe
注册一个主办方(在初始租约时间后),该主办方在不同于远程类型中所指定的时间续订租约。请注意,MyClientSponsor
扩展 MarshalByRefObject 以通过对远程租约管理器的引用进行传递;如果没有这样做,而是用 SerializableAttribute 属性修饰,则此主办方将通过值传递并正常执行,但在服务器应用程序域中除外。
该应用程序可在单台计算机上运行或通过网络运行。如果要在网络上运行该应用程序,必须用远程计算机的名称替换客户端配置中的“localhost”。
此示例使用以 Visual Basic 和 C# 编写的代码。提供了 RemoteType.cs
和 CAOClient.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>