遠端處理範例:存留期
本主題專門說明一項為了在現有應用程式中提供回溯相容性而保留的舊有技術,不建議用於新的開發工作。分散式應用程式應使用 Windows Communication Foundation (WCF) 進行開發。
下列程式碼範例示範幾種存留期租用期案例。Client.exe
會註冊贊助者 (在一開始的租用期間過後) 並更新 TimeSpan 的租用期 (與 ClientActivatedType.InitializeLifetimeService()
中指定的租用期不同)。請注意,由於 MyClientSponsor
會延伸 MarshalByRefObject,因此可以傳址方式傳遞給租用管理員 (在 Server.exe
應用程式定義域中)。這個應用程式會在單一電腦或網路上執行。如果您要透過網路執行這個應用程式,您必須以遠端電腦的名稱取代用戶端組態中的 "localhost"。
注意: |
---|
.NET 遠端處理依預設不執行驗證或加密。因此,建議您採取所有必要的步驟,以驗證用戶端或伺服器的識別,然後再與其進行遠端互動。由於 .NET 遠端處理應用程式需要 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>