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).

c2swb8ah.Caution(it-it,VS.100).gifAttenzione:
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

  1. Salvare tutti i file in una directory denominata RemoteIIS.

  2. 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
    
  3. Creare una sottodirectory \bin e copiare ServiceClass.dll in quella directory.

  4. Creare un'applicazione in IIS. Creare l'alias dell'applicazione "HttpBinary" e impostare la directory di origine sulla directory "RemoteIIS".

  5. 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 e GetServerString restituirà "***unavailable***" per l'alias dell'utente. Per impedire che ciò accada, deselezionare accesso anonimo.

  6. 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)

Altre risorse

Esempi di .NET Remoting