Web Service Dopo le applicazioni desktop e quelle per Internet, i servizi Web sono la terza componente essenziale delle applicazioni.net. I Web Service sono una nuova tecnologia che permette la realizzazione di applicazioni basate su componenti distribuiti. Il termine distribuiti si riferisce al fatto che i componenti sono in esecuzione su computer differenti, dunque implica un protocollo di comunicazione di rete per la comunicazione tra il componente e il programma che lo utilizza. Molti programmi che costituiscono l ossatura del framework.net in termini di servizi alle applicazioni consentono di comunicare attraverso servizi Web. Un esempio è BizTalk Server (Figura 1), il software di Microsoft che si occupa dell integrazione di sistemi, impiegati e partner commerciali. Questo server capisce le tecnologie alla base dei servizi Web e può essere integrato nelle proprie applicazioni precisamente grazie a questi. In che cosa si differenziano i Web Service rispetto ad altre tecnologie di programmazione distribuita, come DCOM? I servizi Web sono molto diversi dai componenti DCOM sotto molti aspetti. Innanzitutto, i Web Service comunicano attraverso un protocollo testuale, formalizzato attraverso documenti XML. I componenti DCOM, invece, si servivano di un protocollo prettamente binario. Con un protocollo testuale in luogo di dati binari è più semplice per lo sviluppatore capire il contenuto del messaggio. I Web Service si basano poi in maniera estensiva sul Web, come peraltro suggerisce il loro stesso nome. La comunicazione, infatti, avviene tramite il protocollo http. Questa decisione comporta due vantaggi. In primo luogo, i Web Service aderiscono a standard esistenti e molto diffusi. In secondo luogo, è interessante notare come il protocollo http, veicolato sulla porta 80, sia amichevole nei confronti dei firewall.
2 C# Pocket Figura 1 BizTalk server fa parte dell offerta di Microsoft per la grande azienda. I firewall aziendali bloccano la comunicazione su tutte le porte verso l esterno dell azienda, in modo da proteggere la rete interna contro eventuali attacchi a opera di malintenzionati. La configurazione di DCOM per comunicare con Internet non era affatto semplice, quindi l utilizzo di http permette di semplificare notevolmente il lavoro sistemistico per supportare un applicazione distribuita. Infine, la tecnologia DCOM è strettamente legata a Windows, anche se esistono prodotti software a pagamento per chiamare componenti DCOM da Java o sotto Unix. Il loro utilizzo è tuttavia costoso in termini di licenze, formazione e manutenzione; inoltre può presentare problemi di performance, in quanto viene instaurato un ulteriore livello di software tra il componente e il suo utilizzatore. Al contrario, i Web Service hanno una natura multipiattaforma, basata su standard consolidati, come il protocollo http e la tecnologia XML. Quest ultima, in particolare, permette di codificare informazioni in modo che siano facilmente leggibili da sistemi eterogenei, quindi interpretabili dal PC che utilizza Windows, come dal dispositivo Java, fino ai cellulari o i mainframe. I Web Service rappresentano dunque un alternativa valida per costruire sistemi distribuiti senza limiti di tipologie applicative, di piattaforme tecnologiche o di linguaggio di programmazione.
Web Service 3 La visione dei servizi Web è comunque molto più ampia, in quanto non si limita a un contesto applicativo locale, all interno dei quattro muri dell azienda. Piuttosto, ha una visione globale e si propone come standard per allacciare la comunicazione tra aziende diverse, sparse in tutto il mondo. I Web Service sono uno strumento per gestire il business tradizionale attraverso la rete, per ottimizzare e automatizzare le comunicazioni tra le aziende. Una pila di tecnologie I Web Service si basano su un insieme di tecnologie che sono state costruite negli anni da Microsoft insieme ad altri partner, come IBM. Per prima cosa è nato il protocollo di comunicazione a basso livello, poi è stato aggiunto un linguaggio per la descrizione dei servizi, infine l insieme delle tecnologie di base è stato completato da un registro di servizi e aziende presenti in tutto il mondo. Successivamente all introduzione di queste tecnologie di base, sono stati aggiunti numerosi altri elementi, indispensabili per supportare le specifiche iniziali. Queste, infatti, presentavano notevoli lacune, sia in merito agli elementi di base sia a quelli più avanzati. Negli anni che sono seguiti alla loro prima introduzione sono stati quindi aggiunti molti elementi, riassunti nella Figura 2. Figura 2 La pila delle tecnologie dei servizi Web.
4 C# Pocket Molte delle specifiche illustrate sono state sottoposte a organizzazioni internazionali con l intento di essere standardizzate. Molte tecnologie, quindi, sono standard e supportate da altre piattaforme. Utilizzando queste tecnologie si può ottenere l interoperabilità tra le diverse piattaforme. Utilizzare invece le ultime specifiche potrebbe portare a situazioni di incompatibilità. Il protocollo di comunicazione utilizzato dai servizi Web è SOAP (Simple Object Access Protocol). Il vantaggio di utilizzare gli strumenti di sviluppo Visual Studio.NET è quello di potersi concentrare sullo sviluppo delle applicazioni, senza preoccuparsi dei dettagli di basso livello. Un esempio concreto Per capire come realizzare un Web Service in concreto, si vedrà ora come sviluppare un semplice servizio che esegue le quattro operazioni matematiche di base. Si vedrà poi come realizzare un client che utilizzi il servizio. La creazione di un Web Service in Visual Studio.NET si basa sulla tecnologia ASP.NET e su Internet Information Services. Per realizzare un nuovo servizio è necessario scegliere, nella finestra Nuovo Progetto di Visual Studio, la tipologia ASP.NET Web Service. Lo strumento si occuperà di creare lo scheletro di un servizio e una directory virtuale nel Web server IIS installato sulla macchina di sviluppo. Non è possibile utilizzare Visual Studio C# Express per sviluppare Web Service. È necessario utilizzare Visual Studio completo o Visual Web Developer. Il vantaggio di sviluppare un Web Service in C# è la possibilità di concentrarsi sulle funzionalità anziché sui protocolli. Un servizio Web è infatti una semplice classe che deriva da System.Web.Services. WebService e in cui il programmatore ha inserito opportuni attributi per definire le modalità di presentazione all esterno del servizio. Gli attributi della classe devono includere il Namespace, che rappresenta, sostanzialmente, lo stesso concetto presente in C#, ma applicato al servizio Web. Questo è formalizzato come un URL. Per definire invece quali metodi debbano essere esposti attraverso la rete, si utilizza l attributo WebMethod. Altri metodi della classe privi di tale attributo non potranno essere visti dai client.
Web Service 5 I metodi esposti dal servizio sono Addizione, Sottrazione, Moltiplicazione e Divisione. Il codice sorgente completo del servizio è il seguente: using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Web; using System.Web.Services; namespace Pocket_CSharp / <summary> / Web Service per le 4 operazioni / principali della matematica / </summary> [WebService(Namespace = "http:tempuri.org/pocket_csharp/", Name="Operazioni", Description="Le 4 operazioni principali")] public class Operazioni : System.Web.Services.WebService #region Costruttore public Operazioni() InitializeComponent(); #region Component Designer generated code anche in questo caso è presente il codice di base per operare con componenti visuali, anche se all atto pratico questo servizio non ne fa uso alcuno private IContainer components = null; private void InitializeComponent() protected override void Dispose(bool disposing ) if(disposing && components!= null) components.dispose();
6 C# Pocket base.dispose(disposing); #region Addizione [WebMethod] Implementazione dell operazione di somma public float Addizione(float addendo1, float addendo2) return addendo1 + addendo2; #region Sottrazione [WebMethod] Implementazione dell operazione di differenza public float Sottrazione(float minuendo, float sottraendo) return minuendo - sottraendo; #region Moltiplicazione [WebMethod] Implementazione dell operazione di prodotto public float Moltiplicazione(float fattore1, float fattore2) return fattore1 * fattore2; #region Divisione [WebMethod] Implementazione dell operazione di divisione public float Divisione(float numeratore, float denominatore) return numeratore / denominatore;
Web Service 7 L implementazione dei metodi esposti dal servizio è molto semplice e non fa altro che utilizzare gli operatori del linguaggio per eseguire le operazioni richieste. Per provare il servizio è sufficiente eseguire il progetto perché si venga rediretti all indirizzo Web al quale è presentato (Figura 3). Figura 3 Il sommario del servizio Operazioni. Sviluppo del client Per usufruire del servizio è stato realizzato un programma client la cui interfaccia utente replica l aspetto di una semplice calcolatrice (Figura 4). Figura 4 Il client del servizio Operazioni.
8 C# Pocket All interfaccia utente è collegato, premendo il pulsante Risultato, un brano di codice che crea un riferimento a un oggetto che rappresenta il servizio. Per fare questo è sufficiente creare un oggetto di tipo Operazioni: localhost.operazioni op = new localhost.operazioni(); Il codice sorgente è illustrato nel listato seguente. Si noti che per motivi di spazio è stato tagliato nelle parti meno essenziali, legate alla gestione dei singoli pulsanti dei numeri: using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace Pocket_CSharp.Calcolatrice il client è implementato come una finestra public class Calc : System.Windows.Forms.Form private System.Windows.Forms.Button piu; private System.Windows.Forms.Button meno; private System.Windows.Forms.Button per; private System.Windows.Forms.Button diviso; private System.Windows.Forms.TextBox display; private System.Windows.Forms.Button uno; private System.Windows.Forms.Button due;... altri pulsanti private System.Windows.Forms.Button nove; private System.Windows.Forms.Button risultato; private System.ComponentModel.Container components = null; private float a = 0; private float b = 0; private System.Windows.Forms.Button button1; private string operation; il costruttore si limita ad inizializzare i componenti public Calc()
Web Service 9 InitializeComponent(); protected override void Dispose(bool disposing) if( disposing ) if (components!= null) components.dispose(); base.dispose( disposing ); #region Windows Form Designer generated code private void InitializeComponent() this.display = new System.Windows.Forms.TextBox(); this.piu = new System.Windows.Forms.Button(); this.meno = new System.Windows.Forms.Button(); this.per = new System.Windows.Forms.Button(); this.diviso = new System.Windows.Forms.Button(); this.tre = new System.Windows.Forms.Button(); this.due = new System.Windows.Forms.Button(); this.uno = new System.Windows.Forms.Button(); this.sei = new System.Windows.Forms.Button(); this.cinque = new System.Windows.Forms.Button(); this.quattro = new System.Windows.Forms.Button(); this.nove = new System.Windows.Forms.Button(); this.otto = new System.Windows.Forms.Button(); this.sette = new System.Windows.Forms.Button(); this.risultato = new System.Windows.Forms.Button(); this.button1 = new System.Windows.Forms.Button(); this.suspendlayout(); display
10 C# Pocket this.display.location = new System.Drawing.Point(8, 8); this.display.name = "display"; this.display.size = new System.Drawing.Size(192, 20); this.display.tabindex = 0; this.display.text = "0"; da questo punto inizia il codice che imposta le proprietà di tutti i pulsanti della finestra this.piu.font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); this.piu.location = new System.Drawing.Point(168, 160); this.piu.name = "piu"; this.piu.size = new System.Drawing.Size(32, 32); this.piu.tabindex = 1; this.piu.text = "+"; this.piu.click += new System.EventHandler(this.piu_Click);... uno this.uno.font = new System.Drawing.Font( "Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); this.uno.location = new System.Drawing.Point(8, 160); this.uno.name = "uno"; this.uno.size = new System.Drawing.Size(32, 32); this.uno.tabindex = 7; this.uno.text = "1";
Web Service 11 this.uno.click += new System.EventHandler(this.uno_Click);... inizializza la finestra ed aggiunge alla stessa i pulsanti this.autoscalebasesize = new System.Drawing.Size(5, 13); this.clientsize = new System.Drawing.Size(208, 230); this.controls.add(this.button1); this.controls.add(this.risultato); this.controls.add(this.sette); this.controls.add(this.otto); this.controls.add(this.nove); this.controls.add(this.quattro); this.controls.add(this.cinque); this.controls.add(this.sei); this.controls.add(this.uno); this.controls.add(this.due); this.controls.add(this.tre); this.controls.add(this.diviso); this.controls.add(this.per); this.controls.add(this.meno); this.controls.add(this.piu); this.controls.add(this.display); this.name = "Calc"; this.text = "Calcolatrice"; this.resumelayout(false); [STAThread] static void Main() Application.Run(new Calc()); da qui in avanti iniziano i gestori di evento per la selezione dei pulsanti della finestra private void piu_click(object sender,
12 C# Pocket this.operation = "+"; private void meno_click(object sender, this.operation = " "; private void per_click(object sender, this.operation = "*"; private void diviso_click(object sender, this.operation = "/"; metodo presente per tutti i pulsanti imposta i valori da utilizzare per le operazioni. È possibile utilizzare solo numeri a singola cifra private void uno_click(object sender, if(a == 0) this.a = (float) (Int32.Parse(this.uno.Text)); else if(b == 0) this.b = (float) (Int32.Parse(this.uno.Text)); display.text = this.uno.text; il gestore di evento che gestisce il risultato crea un oggetto Operazioni che viene invocato in modo diverso in funzione dell operazione selezionata in precedenza private void risultato_click(object sender,
Web Service 13 localhost.operazioni op = new localhost.operazioni(); switch (this.operation) case "+": this.display.text = op.addizione(a, b).tostring(); this.a = op.addizione(a, b); this.b = 0; break; case " ": this.display.text = op.sottrazione(a, b).tostring(); this.a = op.sottrazione(a, b); this.b = 0; break; case "*": this.display.text = op.moltiplicazione(a, b).tostring(); this.a = op.moltiplicazione(a, b); this.b = 0; break; case "/": this.display.text = op.divisione(a, b).tostring(); this.a = op.divisione(a, b); this.b = 0; break; questo gestore di evento inizializza la calcolatrice, azzerando gli operandi private void button1_click(object sender, this.a = 0; this.b = 0; this.display.text = "0";