Ospitare un servizio WCF su un worker role di Windows Azure

I ruoli che è possibile deployare sulla piattaforma Windows Azure sono di due tipi: web e worker. Il primo non è altro che un insieme di siti web che vengono automaticamente deployati e configurati su IIS della macchina virtuale. Il worker è invece adatto per attività da eseguire ad intervalli o per eseguire codice intensivo il cui lavoro non dipende da interazioni con l'utente attraverso un sito internet.

Quando si realizza un servizio WCF viene automatico pensare di ospitarlo attraverso il web role e il relativo file svc che rappresenta l'endpoint HTTP. Questo però non è necessariamente obbligatorio, perché anche un worker role può ospitare un servizio WCF o più in generale rispondere su HTTP/TCP. I motivi per cui non si voglia usare un web role per ospitare un servizio possono essere moltiplici: dalla necessità di interagire direttamente con il motore, alla necessità di voler "risparmiare" sul numero dei ruoli, aggregando attività e servizi sotto un unico ruolo.

Per poter raggiungere questo scopo occorre innanzitutto vedere lo script #286 dove si è visto come definire gli endpoint per un ruolo. In questo caso, siccome si vuole utilizzare il basicHttpBinding, l'endpoint dev'essere di tipo http, come nell'esempio seguente.

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition>
  <WorkerRole name="WCFWorkerRole"
        vmsize="Small">
    <Endpoints>
      <InputEndpoint name="Service"
               protocol="http"
               port="80" />
    </Endpoints>
  </WorkerRole>
</ServiceDefinition>

A questo punto sul metodo Run del worker role si utilizza la classe ServiceHost per istanziare il motore che ascolta e processa le chiamate al servizio. Poiché le istanze dei ruoli possono essere molteplici e gli ip delle macchine virtuali sono assegnati dinamicamente, è necessario definire l'URI di ascolto del servizio, concatenando IP e al resto dell'URI.

public override void Run()
{
  // Determino l'uri in base all'ip
  string address = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Service"].IPEndpoint.ToString();
  Trace.WriteLine("Listening on " + address);

  // Avvio il servizio di ascolto
  ServiceHost host = new ServiceHost(typeof(ServiceTest), new Uri("http://" + address + "/TestService"));
  host.AddServiceEndpoint(typeof (ServiceTest), new BasicHttpBinding(), "");
  host.Open();
}

Ora il servizio è pronto e si mette in ascolto all'avvio del worker role. E' necessario però fare un'ultima operazione. Per ascoltare sulla porta 80 il servizio necessita di diritti che il processo in cui gira il worker role normalmente non detiene, per cui è necessario utilizzare il tool netsh per darli e permettere al ServiceHost di mettersi in ascolto. Per questo scopo, siccome dobbiamo configurare questi permessi ad ogni avvio del ruolo, vengono in aiuto i task che possiamo eseguire automaticamente allo startup. Come visto nello script #284, occorre specificare l'exe da eseguire che nel caso specifico è una console application che occorre preparare.

<Startup>
  <Task commandLine="AzurePortDetector.exe"
      executionContext="elevated"
      taskType="background">
  </Task>
</Startup>

L'applicazione non fa altro che chiamare netsh creando l'uri di ascolto in base all'endpoint configurato nel worker role. Di seguito il codice che esegue tale configurazione.

static void Main(string[] args)
{
  int port = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Service"].IPEndpoint.Port;
  Process.Start("netsh", string.Format("http add urlacl url=http://+:{0}/TestService user=everyone listen=yes delegate=yes", port));
}

Una volta compilato occorre includere l'exe e il file .config come content all'interno del worker role. I passi sono molteplici, ma nell'allegato è possibile trovare un progetto completo di esempio dal quale è possibile partire. Occorre inoltre prestare attenzione al fatto che nel caso di molteplici istanze il balancer di Azure distribuirà le chiamate su tutti i servizi.

Commenti

Ospitare un servizio WCF su un worker role di Windows Azure (#290) 1010 3
| Condividi su: Twitter, Facebook, LinkedIn, Google+

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi