Introduzione a WCF 4.0: Hosting dei servizi

Scritto da  Pietro Libro il mercoledì 3 novembre 2010
Linguaggio: C#,VB   •  Framework: 4.0   •  Livello: 100

Download sorgenti


In quest'ultimo articolo dedicato alla tecnologia WCF 4, vedremo le diverse soluzioni che possono essere adottate per eseguire l'hosting (dall'inglese to host, ospitare) del nostro servizio WCF Calculator implementato nelle puntate precedenti.
Il primo tipo di hosting che andiamo ad analizzare è relativo ad ASP.NET Development Server.

ASP.NET Development Server Hosting

Apriamo la solution contenente il progetto del nostro servizio e nel Solution Esplorer di Visual Studio 2010 visualizziamo il menu contestuale (attivabile a partire dal nome della soluzione) e scegliamo Add |New Web Site

Figura_1

Nella dialog visualizzata scegliamo  Empty Web Site e denominiamo il  progetto in  CalculatorAspNetService.

Figura_2

A questo punto nel Solution Explorer dovremmo avere un progetto Web Site contenente il solo file Web.Config. Rendiamo il progetto CalculatorAspNetService di avvio (Startup Project): selezioniamo il progetto nel Solution Explorer e con il tasto destro visualizziamo il menu contestuale e scegliamo Set As Startup Project:

Figura_3

A questo punto dobbiamo aggiungere un riferimento al nostro servizio, per cui, tasto destro su CalculatorAspNetService e dal menu contestuale scegliamo Add Reference. Nella dialog References dalla lista dei progetti presenti nella scheda Projects scegliamo Domus.WCF.CalculatorService (il file Domus.WCF.CalculatorService.dll verrà aggiunto nella cartella Bin del progetto Web Site).
I passi fino a questo punto eseguiti non sono sufficienti per eseguire l'hosting del servizio, mancano ancora un paio di passaggi.  ASP.NET Development Server è presente in Visual Studio dalla versione 2005 ed è un Web Server pensato per essere utilizzato dagli sviluppatori con funzioni simili a quelle fornite da IIS (Internet Information Server), ma rispetto a quest'ultimo ASP.NET Development Server ha molte limitazioni. Di default  ASP.NET Development Server utilizzata una porta dinamica ogni volta che viene eseguito, ma in questo modo i client che devono utilizzare il nostro servizio avrebbero delle difficoltà ad usarlo (ovvero non lo troverebbero non conoscendo l'address esatto a cui puntare). E' necessario  cambiare il comportamento del Web Server impostando nella finestra delle proprietà relative al progetto Web Site il valore di Use Dynamic Ports a False e di Port su un numero di porta valido (dipendente dalla configurazione del computer su cui viene eseguito l'hosting del servizio). Ad esempio sul mio PC un valore valido è 8081.

Figura_4

Normalmente ASP.NET Development Server viene eseguito quando si esegue il debugging o l'Unit Testing di un progetto, ma può essere anche avviato da riga di comando in questo modo:

C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0>start /B webdev.webserver40.exe /port:8081 /path:"C:\Users\Pietro\Documents\Visual Studio 2010\WebSites\CalculatorAspNetService" /vpath:/CalculatorAspNetService

Il quale una volta lanciato avvierà una nuova istanza dell'ASP.NET Development Server come mostrato nella figura seguente:

Figura_5

Per rendere il nostro servizio funzionante mancano ancora due cose:  aggiungere un file con estensione ".svc" e modificare il file Web.Config. Aggiungiamo il file CalculatorAspNetService.svc: dal solito menu contestuale visualizzabile nel Solution Explorer tramite click del tasto destro sul nome del progetto,  scegliamo la voce Add New Item e nella finestra visualizzata Text File specificando il nome precedentemente indicato.

Figura_6

Dopo aver premuto "Add", Visual Studio aprirà direttamente il file per poter scriverne il contenuto:

 <%@ ServiceHost Service="Domus.WCF.CalculatorService.Calculator" %>

Modifichiamo il contenuto del Web.Config in questo modo:

<?xml version="1.0"?>
<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0"/>
    </system.web>
    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
    </system.webServer>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="CalculatorServiceBehaviors">
                    <serviceMetadata httpGetEnabled="true"/>
                    <serviceDebug includeExceptionDetailInFaults="false"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service name="Domus.WCF.CalculatorService.Calculator" behaviorConfiguration="CalculatorServiceBehaviors">
                <endpoint address="" binding="wsHttpBinding" contract="Domus.WCF.CalculatorService.ICalculator"/>
                <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
            </service>
        </services>
    </system.serviceModel>
</configuration>

Prima di eseguire impostiamo come pagina di partenza del Web Site il file .svc creato. Premendo F5 dovrebbe essere visualizzata la finestra di dialogo corrente:

Figura_7

Lasciamo il flag impostato sulla posizione di default per abilitare il debugging del sito web e premiamo "OK". Se tutto è stato eseguito in modo corretto nel browser dovremmo visualizzare la seguente pagina:

Figura_8

Premendo il link in alto nella finestra visualizzeremo il wsdl del servizio (su IE9 bisogna abilitare il Compatibility View)
Abbiamo così visto il primo modo di eseguire l'hosting di un servizio WCF, ma l'hosting può essere eseguito anche all'interno di applicazioni managed come un'applicazione web, un'applicazione Windows Forms  o command-line. Questa metodologia di hosting consente agli sviluppatori il pieno controllo sul ciclo di vita del nostro servizio WCF soprattutto per quanto concerne il debugging ed il testing, ma ci sono forti limitazioni quali ad esempio l'avvio automatico del servizio, limitato supporto ad alta disponibilità, gestione, robustezza e distribuzione.

Console Hosting

Proviamo ad eseguire l'hosting della nostro servizio in un'applicazione console.  Come al solito, aggiungiamo un nuovo progetto, questa volta di tipo Console (i passi da seguire sono gli stessi dell'hosting per ASP.NET Development Server, solo che dobbiamo scegliere Add New Project invece di Add New Web Site). Nella finestra di dialogo Add New Project selezioniamo il template Console Application e lo denominiamo come CalculatorConsoleHosting e premiamo "OK".

Figura_9

Aggiungiamo un riferimento al progetto Domus.WCF.CalculatorService ed impostiamo il progetto come d'avvio (Startup Project). Aggiungiamo inoltre un riferimento al System.ServiceModel e System.Configuration dalla lista nella scheda ".NET" presente nella dialog "Add References" visualizzabile nello stesso modo in cui abbiamo aggiunto un riferimento al progetto con il nostro servizio WCF.

Figura_10

Prima di procedere è necessario aggiungere un file di configurazione al progetto. Nel Solution Explorer,  tasto destro su CalculatorConsoleHosting, poi dal menu  Add |New Item. Nella finestra visualizzata scegliamo Application Configuration File e premiamo "Add". Modifichiamo il contenuto del file in questo modo:

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="HTTPBaseAddress" value="http://localhost:8082/HostingConsole/CalculatorService"/>
  </appSettings>
  <system.web>
    <compilation debug="false" targetFramework="4.0"/>
  </system.web>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="CalculatorServiceBehaviors">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="Domus.WCF.CalculatorService.Calculator" behaviorConfiguration="CalculatorServiceBehaviors">
        <endpoint address="" binding="wsHttpBinding" contract="Domus.WCF.CalculatorService.ICalculator"/>
        <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
      </service>
    </services>
  </system.serviceModel>
</configuration>

Modifichiamo il contenuto di Program.cs . Aggiungiamo due statement Using:

using System.ServiceModel;
using System.Configuration;

e modifichiamo il contenuto del Main:

        static void Main(string[] args)
        {
            Type calculatoServiceType = typeof(Domus.WCF.CalculatorService.Calculator);

            string httpBaseAddress = ConfigurationManager.AppSettings["httpBaseAddress"];
            ServiceHost host = new ServiceHost(calculatoServiceType, new Uri[] { new Uri(httpBaseAddress) });

            host.Open();

            Console.WriteLine("CalculatorService is now running...");
            Console.WriteLine("Press any type to stop the service.");
            Console.ReadKey();

            host.Close();
        }

Non ci resta che premere F5 per eseguire il nostro servizio:

Figura_12

E' sufficiente copiare ed incollare l'indirizzo http://localhost:8082/HostingConsole/CalculatorService?wsdl nel browser per testarne il funzionamento.

L'hosting del servizio in un'applicazione  Windows Form o Windows Service è un'operazione del tutto analoga a quanto descritto per il tipo console. Passiamo quindi ad Internet Information Server.

Hosting In Internet Information Server

IIS è la migliore delle opzioni per eseguire l'hosting di un servizio WCF perché fornisce tutte le proprietà necessario ad un corretto funzionamento dei servizi: gestione, robustezza, sicurezza, efficienza ecc … Uno dei principali svantaggi nelle versione precedenti a IIS 7.0 è il forte accoppiamento tra ASP.NET e Web Services che limitava l'utilizzo ai protocolli HTTP e HTTPS. Con IIS 7.0 e superiori abbiamo invece la possibilità di utilizzare TCP, Pipe e MSMQ, oltre ad http e HTTPS. Anche se non è oggetto di questo articolo, è importante sottolineare che secondo della configurazione del Web Site in cui viene eseguito l'hosting del servizio (ad esempio in un ambiente load-balanced) potrebbero esserci dei problemi con la session di WCF che viene persistita in memoria (in questo caso è necessario utilizzare SQL Server o ASP.NET State Server). Ora invece vediamo quali sono i passi necessari ad eseguire l'hosting del nostro servizio in IIS.
Per prima cosa creiamo una cartella nel File System, ad esempio C:\Domus\WCF\CalculatorService.
In questa cartella dobbiamo copiare i file:

  1. Domus.WCF.CalculatorService.dll (Nella sottodirectory Bin)
  2. CalculatorAspNetService.svc
  3. Web.Config

Gli ultimi due file sono stati creati quando abbiamo sviluppato il progetto Web Site per eseguire l'hosting tramite ASP.NET Development Server. Supponendo che IIS sia installato e configurato correttamente:

  1. Tramite il prompt dei comandi in modalità amministratore, lanciamo il manager di IIS attraverso il comando start inetmgr ;
  2. Nella struttura ad albero a sinistra della finestra visualizzata espandiamo i nodi fino a rendere visibile la voce Default Web Site. Selezioniamo il nodo e visualizziamo il menu contestuale con il tasto destro e scegliamo Aggiungi applicazione …;
  3. Nella finestra visualizzata nel campo Alias specifichiamo il valore IISCalculatorService e specifichiamo come percorso fisico C:\Domus\WCF\CalculatorService. Se necessario, dobbiamo specificare il valore dell'Application Pool sulla versione 4.0 del .Net.

Figura_13

Dopo aver premuto "OK" il nostro lavoro è terminato (in teoria, secondo dei requisiti bisognerebbe modificare le varie impostazioni di IIS per l'autenticazione, Esplorazione Directory, pagina iniziale ecc …). Supponendo che le impostazioni di default siano sufficienti, digitando o copiando ed incollando l'indirizzo http://localhost/iiscalculatorService/CalculatorAspNetService.svc  dovremmo visualizzare la pagina web del servizio.

Non ci resta che creare un client che ci permetta di testare il comportamento dell'servizio nelle sue "varie forme di hosting".

Al solito, aggiungiamo alla nostra soluzione un nuovo progetto di tipo Console che denominiamo CalculatorConsoleClient e aggiungiamo i soliti References a System.ServiceModel , System.Configuration e System.Runtime.Serialization. Invece di utilizzare Visual Studio per la creazione delle classi proxy necessarie per interfacciarsi con il servizio, questa volta utilizzeremo l'utility a riga di comando ScvUtil.exe aprendo una nuova finestra dal prompt dei comandi di Visual Studio 2010 in modalità amministratore (Start | Tutti i programmi | Microsoft Visual Studio 2010 | Visual Studio 2010 Tools) e digitando quanto segue:

C:\Windows\system32>svcutil.exe http://localhost/iiscalculatorService/CalculatorAspNetService.svc?wsdl /out:"C:\Users\Pietro\Documents\Visual Studio 2010\Projects\Domus.WCF.CalculatorService\DomusCalculatorClient\CalculatorService.cs" /config:"C:\Users\Pietro\Documents\Visual Studio2010\Projects\Domus.WCF.CalculatorService\DomusCalculatorClient\App.config"

Alcune osservazioni:

  1. Abbiamo utilizzato il servizio WCF "hostato" su IIS;
  2. Con il parametro  /out indichiamo il percorso dove salvare il file con estensione .cs generato (e' possibile cambiare il linguaggio specificando il parametro /language);
  3. Con il parametro /config indichiamo il percorso dove salvare il file di configurazione App.Config.

Maggiori informazioni sul tool SvcUtil.exe e sul suo utilizzo all'indirizzo http://msdn.microsoft.com/it-it/library/aa347733.aspx.

A questo punto nella root del progetto CalculatorConsoleClient dovremmo trovare i due file generati attraverso SvcUtil.exe, ma questi non sono presenti nel Solution Explorer di Visual Studio: affinché siano visualizzati è necessario selezionare il progetto CalculatorConsoleClient e premere il bottone Show All Files presente nella toolbar di Solution Explorer.

Figura_14

A questo punto per includere i file nel progetto è necessario selezionarli (entrambi o uno alla volta) e dal menu contestuale scegliere Include In Project. Prima di eseguire il nostro client modifichiamo il codice di Program.cs in questo modo:

        static void Main(string[] args)
        {
            CalculatorClient calculator = new CalculatorClient();            
            Console.WriteLine("2^3={0}", calculator.Pow(2, 3));
            Console.ReadKey();
        }

Premendo F5 visualizzeremmo una schermata console simile alla seguente:

Figura_15

Se volessimo eseguire la chiamata verso un altro Hosting è sufficiente cambiare l'indirizzo esposto dall'Endpoint in questo modo:

static void Main(string[] args)
{
   CalculatorClient calculator = new CalculatorClient();
   calculator.Endpoint.Address = new EndpointAddress("http://localhost:8082/HostingConsole/CalculatorService");
   Console.WriteLine("2^3={0}", calculator.Pow(2, 3));
   Console.ReadKey();
}

In questo esempio la chiamata viene eseguita sul servizio "hostato" in IIS. Qualche osservazione prima di concludere: quando abbiamo generato le classi proxy tramite SvcUtil.exe non abbiamo specificato il parametro /async che ci permettere di generare i metodi per l'esecuzione asincrone delle chiamate verso il servizio, in più avremmo potuto generare dinamicamente queste classi direttamente  da codice utilizzando la classe System.ServiceModel.ChannelFactory (http://msdn.microsoft.com/it-it/library/system.servicemodel.channelfactory%28VS.95%29.aspx) .
Siamo così  giunti alla fine di quest'articolo e della mini serie dedicata a WCF 4: abbiamo introdotto i concetti principali, abbiamo visto come creare un semplice servizio, come gestire gli errori ed infine come eseguirne l'hosting e creare un semplice client che possa consumare il servizio. Sono molteplici gli aspetti che dovrebbero essere approfonditi e che in questi quattro articoli abbiamo appena accennato, come ad esempio sicurezza, utilizzo delle transazioni, ambienti distribuiti, il session state di WCF ecc … Argomenti che saranno prenderemo in considerazione in modo approfondito nei prossimi articoli dedicati a questa fantastica tecnologia.


Tags: WCF 4,Hosting

 
x