Share via


Procedura: ospitare un servizio WCF in WAS

In questo argomento vengono delineati i passaggi di base necessari per creare un servizio WCF (Windows Communication Foundation) ospitato nel servizio di attivazione dei processi di Windows, noto anche come WAS. WAS è il nuovo servizio di attivazione dei processi che rappresenta una generalizzazione delle funzionalità di Internet Information Services (IIS) utilizzabili con protocolli di trasporto non HTTP. WCF usa l'interfaccia dell'adattatore listener per comunicare richieste di attivazione ricevute tramite i protocolli non HTTP supportati da WCF, ad esempio TCP, named pipe e Accodamento messaggi.

Questa opzione di hosting richiede che i componenti di attivazione WAS vengano installati e configurati correttamente, ma non richiede la scrittura di codice di hosting come parte dell'applicazione. Per altre informazioni sull'installazione e la configurazione di WAS, vedere Procedura: Installare e configurare i componenti di attivazione WCF.

Avviso

L'attivazione di WAS non è supportata se la pipeline di elaborazione delle richieste del server Web è impostata sulla modalità classica. Se è necessario utilizzare l'attivazione WAS, la pipeline di elaborazione delle richieste del server Web deve essere impostata sulla modalità integrata.

Quando un servizio WCF viene ospitato in WAS, vengono usati i binding standard come di consueto. Tuttavia, quando si utilizzano NetTcpBinding e NetNamedPipeBinding per configurare un servizio ospitato in WAS, è necessario che sia rispettato un vincolo. Quando endpoint diversi utilizzano lo stesso trasporto, le impostazioni dell'associazione devono corrispondere sulle sette proprietà seguenti:

  • ConnectionBufferSize

  • ChannelInitializationTimeout

  • MaxPendingConnections

  • MaxOutputDelay

  • MaxPendingAccepts

  • ConnectionPoolSettings.IdleTimeout

  • ConnectionPoolSettings.MaxOutboundConnectionsPerEndpoint

In caso contrario, l'endpoint che viene inizializzato per primo determina sempre i valori di queste proprietà e gli endpoint aggiunti in seguito generano un'eccezione ServiceActivationException, se non corrispondono alle impostazioni in questione.

Per la copia di origine di questo esempio, vedere l'attivazione TCP.

Per creare un servizio di base ospitato in WAS

  1. Definire un contratto di servizio per il tipo di servizio.

    [ServiceContract]
    public interface ICalculator
    {
       [OperationContract]
       double Add(double n1, double n2);
       [OperationContract]
       double Subtract(double n1, double n2);
       [OperationContract]
       double Multiply(double n1, double n2);
       [OperationContract]
       double Divide(double n1, double n2);
    }
    
    
  2. Implementare il contratto di servizio in una classe del servizio. Si noti che le informazioni sull'indirizzo o sull'associazione non sono specificate nell'implementazione del servizio. Non è necessario, inoltre, scrivere codice per recuperarle dal file di configurazione.

    public class CalculatorService : ICalculator
    {
       public double Add(double n1, double n2)
       {
          return n1 + n2;
       }
       public double Subtract(double n1, double n2)
       {
          return n1 - n2;
       }
       public double Multiply(double n1, double n2)
       {
          return n1 * n2;
       }
       public double Divide(double n1, double n2)
       {
          return n1 / n2;
       }
    }
    
    
  3. Creare un file Web.config per definire l'associazione NetTcpBinding che CalculatorService deve utilizzare.

    <?xml version="1.0" encoding="utf-8" ?>  
    <configuration>  
      <system.serviceModel>  
        <bindings>  
          <netTcpBinding>  
            <binding portSharingEnabled="true">  
              <security mode="None" />  
            </binding>  
          </netTcpBinding>  
        </bindings>  
      </system.serviceModel>  
    </configuration>  
    
  4. Creare un file Service.svc contenente il codice seguente.

    <%@ServiceHost language=c# Service="CalculatorService" %>
    
  5. Posizionare il file Service.svc nella directory virtuale di IIS.

Per creare un client che utilizzi il servizio

  1. Usare lo strumento ServiceModel Metadata Utility Tool (Svcutil.exe) dalla riga di comando per generare il codice dai metadati di servizio.

    Svcutil.exe <service's Metadata Exchange (MEX) address or HTTP GET address>
    
  2. Il client generato contiene l'interfaccia ICalculator che definisce il contratto di servizio che l'implementazione del client deve soddisfare.

    //Generated interface defining the ICalculator contract	
    [System.ServiceModel.ServiceContractAttribute(
    Namespace="http://Microsoft.ServiceModel.Samples", ConfigurationName="Microsoft.ServiceModel.Samples.ICalculator")]
    public interface ICalculator
    {
    
        [System.ServiceModel.OperationContractAttribute(
    Action="http://Microsoft.ServiceModel.Samples/ICalculator/Add", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/AddResponse")]
        double Add(double n1, double n2);
    
            [System.ServiceModel.OperationContractAttribute(
    Action="http://Microsoft.ServiceModel.Samples/ICalculator/Subtract", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/SubtractResponse")]
        double Subtract(double n1, double n2);
    
            [System.ServiceModel.OperationContractAttribute(
    Action="http://Microsoft.ServiceModel.Samples/ICalculator/Multiply", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/MultiplyResponse")]
        double Multiply(double n1, double n2);
    
            [System.ServiceModel.OperationContractAttribute(
    Action="http://Microsoft.ServiceModel.Samples/ICalculator/Divide", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/DivideResponse")]
        double Divide(double n1, double n2);
    }
    
  3. L'applicazione client generata contiene inoltre l'implementazione di ClientCalculator. Si noti che le informazioni sull'indirizzo e sull'associazione non sono specificate nell'implementazione del servizio. Non è necessario, inoltre, scrivere codice per recuperarle dal file di configurazione.

    // Implementation of the CalculatorClient
    public partial class CalculatorClient : System.ServiceModel.ClientBase<Microsoft.ServiceModel.Samples.ICalculator>, Microsoft.ServiceModel.Samples.ICalculator
    {
    
        public CalculatorClient()
        {
        }
    
        public CalculatorClient(string endpointConfigurationName) :
                base(endpointConfigurationName)
        {
        }
    
        public CalculatorClient(string endpointConfigurationName, string remoteAddress) :
                base(endpointConfigurationName, remoteAddress)
        {
        }
    
        public CalculatorClient(string endpointConfigurationName,
                System.ServiceModel.EndpointAddress remoteAddress) :
                base(endpointConfigurationName, remoteAddress)
        {
        }
    
        public CalculatorClient(System.ServiceModel.Channels.Binding binding, 				System.ServiceModel.EndpointAddress remoteAddress) :
                base(binding, remoteAddress)
        {
        }
    
        public double Add(double n1, double n2)
        {
            return base.Channel.Add(n1, n2);
        }
    
        public double Subtract(double n1, double n2)
        {
            return base.Channel.Subtract(n1, n2);
        }
    
        public double Multiply(double n1, double n2)
        {
            return base.Channel.Multiply(n1, n2);
        }
    
        public double Divide(double n1, double n2)
        {
            return base.Channel.Divide(n1, n2);
        }
    }
    
  4. Anche la configurazione del client che utilizza la classe NetTcpBinding viene generata da Svcutil.exe. Quando si utilizza Visual Studio, questo file deve essere denominato App.config.

    
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <system.serviceModel> 
            <bindings> 
                <netTcpBinding> 
                    <binding name="NetTcpBinding_ICalculator"> 
                        <security mode="None"/> 
                    </binding> 
                </netTcpBinding> 
            </bindings> 
            <client> 
                <endpoint 
                  address="net.tcp://localhost/servicemodelsamples/service.svc" 
                  binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ICalculator" 
                  contract="ICalculator" name="NetTcpBinding_ICalculator" /> 
            </client>
        </system.serviceModel> 
    </configuration>
    
    
  5. Creare un'istanza di ClientCalculator in un'applicazione, quindi chiamare le operazioni del servizio.

    //Client implementation code.
    class Client
    {
        static void Main()
        {
            // Create a client with given client endpoint configuration
            CalculatorClient client = new CalculatorClient();
    
            // Call the Add service operation.
            double value1 = 100.00D;
            double value2 = 15.99D;
            double result = client.Add(value1, value2);
            Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
    
            // Call the Subtract service operation.
            value1 = 145.00D;
            value2 = 76.54D;
            result = client.Subtract(value1, value2);
            Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);
    
            // Call the Multiply service operation.
            value1 = 9.00D;
            value2 = 81.25D;
            result = client.Multiply(value1, value2);
            Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
    
            // Call the Divide service operation.
            value1 = 22.00D;
            value2 = 7.00D;
            result = client.Divide(value1, value2);
            Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
    
            //Closing the client gracefully closes the connection and cleans up resources
            client.Close();
    
            Console.WriteLine();
            Console.WriteLine("Press <ENTER> to terminate client.");
            Console.ReadLine();
        }
    }
    
  6. Compilare ed eseguire il client.

Vedi anche