Esempio di .NET Remoting: hosting in Internet Information Services (IIS)
Questo argomento è specifico di una tecnologia legacy mantenuta per una questione di compatibilità con le applicazioni esistenti di versioni precedenti e non è consigliato per il nuovo sviluppo. Le applicazioni distribuite devono ora essere sviluppate utilizzando Windows Communication Foundation (WCF).
Nell'esempio seguente viene implementato un servizio Web di base con alcune complicazioni. BinaryFormatter viene utilizzato perché il payload è più compatto e il sistema impiega meno tempo per serializzare e deserializzare il flusso. Inoltre, se in Internet Information Services (IIS) si sta utilizzando l'Autenticazione integrata di Windows (anche nota come l'autenticazione NTLM), il server autentica il client e quindi restituisce al client l'identità che IIS è stato in grado di autenticare. È infine possibile consentire di proteggere il servizio Web modificando l'URL nel file di configurazione del client per utilizzare "https" come schema di protocollo e configurare IIS per richiedere la crittografia Secure Sockets Layer (SSL) per quella directory virtuale (l'esempio non illustra questo processo).
Attenzione: |
---|
Nei servizi remoti di .NET Framework l'autenticazione o la crittografia non viene eseguita per impostazione predefinita. È pertanto consigliato che vengano effettuati tutti i passaggi necessari per assicurarsi dell'identità di client o server prima di interagirvi in modalità remota. Poiché l'esecuzione delle applicazioni di .NET Framework Remoting richiede autorizzazioni di tipo FullTrust, se si concede l'accesso al proprio server a un client non autorizzato, questi potrebbe eseguire codice come se fosse completamente attendibile. Autenticare sempre gli endpoint e crittografare i flussi di comunicazione eseguendo l'hosting dei tipi remoti in Internet IIS o compilando una coppia di sink di canale personalizzata per eseguire questo lavoro. |
Per compilare ed eseguire l'esempio
Salvare tutti i file in una directory denominata RemoteIIS.
Compilare l'esempio intero digitando i comandi seguenti al prompt dei comandi:
vbc /t:library ServiceClass.vb vbc /r:System.Runtime.Remoting.dll /r:ServiceClass.dll Client.vb
csc /t:library ServiceClass.cs csc /r:System.Runtime.Remoting.dll /r:ServiceClass.dll Client.cs
Creare una sottodirectory \bin e copiare
ServiceClass.dll
in quella directory.Creare un'applicazione in IIS. Creare l'alias dell'applicazione "HttpBinary" e impostare la directory di origine sulla directory "RemoteIIS".
Impostare il metodo di autenticazione utilizzato per questa directory virtuale sull'Autenticazione integrata di Windows (precedentemente autenticazione NTLM). Se viene selezionato l'accesso anonimo,
HttpContext.Current.User.Identity.Name
sarà null eGetServerString
restituirà"***unavailable***"
per l'alias dell'utente. Per impedire che ciò accada, deselezionare accesso anonimo.Verificare che IIS sia avviato. Al prompt dei comandi, nella directory "RemoteIIS", digitare client.
Questa applicazione è in esecuzione su un solo computer o attraverso una rete. Se si desidera eseguire questa applicazione su una rete, è necessario sostituire "localhost" nella configurazione client con il nome del computer remoto.
ServiceClass
Imports System
Imports System.Runtime.Remoting
Imports System.Web
Public Interface IService
Function GetServerTime() As DateTime
Function GetServerString() As String
End Interface
Public Class ServiceClass
Inherits MarshalByRefObject
Implements IService
Private InstanceHash As Integer
Public Sub New()
InstanceHash = Me.GetHashCode()
End Sub
Public Function GetServerTime() As Date Implements IService.GetServerTime
Return DateTime.Now
End Function
Public Function GetServerString() As String Implements IService.GetServerString
' Use the HttpContext to acquire what IIS thinks the client's identity is.
Dim temp As String = HttpContext.Current.User.Identity.Name
If (temp Is Nothing Or temp.Equals(String.Empty)) Then
temp = "**unavailable**"
End If
Return "Hi there. You are being served by instance number: " _
& InstanceHash.ToString() _
& ". Your alias is: " _
& temp
End Function
End Class
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Threading;
using System.Web;
public interface IService
{
DateTime GetServerTime();
string GetServerString();
}
// IService exists to demonstrate the possibility of publishing only the interface.
public class ServiceClass : MarshalByRefObject, IService
{
private int InstanceHash;
public ServiceClass()
{
InstanceHash = this.GetHashCode();
}
public DateTime GetServerTime()
{
return DateTime.Now;
}
public string GetServerString()
{
// Use the HttpContext to acquire what IIS thinks the client's identity is.
string temp = HttpContext.Current.User.Identity.Name;
if (temp == null || temp.Equals(string.Empty))
temp = "**unavailable**";
return "Hi there. You are being served by instance number: "
+ InstanceHash.ToString()
+ ". Your alias is: "
+ temp;
}
}
Web.config
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown
mode="SingleCall" objectUri="SAService.rem"
type="ServiceClass, ServiceClass"/>
</service>
<channels>
<channel ref="http"/>
</channels>
</application>
</system.runtime.remoting>
</configuration>
Client
Imports System
Imports System.Collections
Imports System.Net
Imports System.Runtime.Remoting
Imports System.Runtime.Remoting.Channels
Imports System.Security.Principal
Public Class Client
Public Shared Sub Main()
' Tells the system about the remote object and customizes the HttpChannel
' to use the binary formatter (which understands that base64 encoding is needed).
RemotingConfiguration.Configure("Client.exe.config", False)
' New proxy for the ServiceClass.
' If you publish only the IService interface, you must use Activator.GetObject.
Dim service As ServiceClass = New ServiceClass()
' Programmatically customizes the properties given to the channel. This sample uses the
' application configuration file.
Dim Props As IDictionary = ChannelServices.GetChannelSinkProperties(service)
Props.Item("credentials") = CredentialCache.DefaultCredentials
' Reports the client identity name.
Console.WriteLine("ConsoleIdentity: " & WindowsIdentity.GetCurrent().Name)
' Writes what the server returned.
Console.WriteLine("The server says : " & service.GetServerString())
Console.WriteLine("Server time is: " & service.GetServerTime())
End Sub
End Class
using System;
using System.Collections;
using System.Net;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Security.Principal;
class Client
{
static void Main(string[] args)
{
// Tells the system about the remote object and customizes the HttpChannel
// to use the binary formatter (which understands that base64 encoding is needed).
RemotingConfiguration.Configure("Client.exe.config", false);
// New proxy for the ServiceClass.
// If you publish only the IService interface, you must use Activator.GetObject.
ServiceClass service = new ServiceClass();
// Programmatically customizes the properties given to the channel. This sample uses the
// application configuration file.
IDictionary Props = ChannelServices.GetChannelSinkProperties(service);
Props["credentials"] = CredentialCache.DefaultCredentials;
// Reports the client identity name.
Console.WriteLine("ConsoleIdentity: " + WindowsIdentity.GetCurrent().Name);
// Writes what the server returned.
Console.WriteLine("The server says : " + service.GetServerString());
Console.WriteLine("Server time is: " + service.GetServerTime());
}
}
Client.exe.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<channels>
<channel ref="http" useDefaultCredentials="true" port="0">
<clientProviders>
<formatter
ref="binary"
/>
</clientProviders>
</channel>
</channels>
<client>
<wellknown
url="https://localhost:80/HttpBinary/SAService.rem"
type="ServiceClass, ServiceClass"
/>
</client>
</application>
</system.runtime.remoting>
</configuration>
Vedere anche
Concetti
Configurazione di applicazioni remote
Hosting di oggetti remoti in Internet Information Services (IIS)