Programmazione client a livello di canale
In questo argomento viene descritto come scrivere un'applicazione di servizio di Windows Communication Foundation (WCF) senza utilizzare la classe System.ServiceModel.ServiceHost e il relativo modello a oggetti associato.
Ricezione di messaggi
Per prepararsi alla ricezione e all'elaborazione di messaggi, è necessario eseguire i passaggi seguenti:
- Creare un'associazione.
- Generare un listener di canale.
- Aprire il listener del canale.
- Leggere la richiesta e inviare una risposta.
- Chiudere tutti gli oggetti canale.
Creazione di un'associazione
Il primo passaggio dell'attesa e della ricezione di messaggi consiste nel creare un'associazione. In WCF sono disponibili molte associazioni incorporate o fornite dal sistema che è possibile utilizzare direttamente creando un'istanza. È inoltre possibile creare un'associazione personalizzata creando un'istanza della classe CustomBinding, operazione che viene eseguita nel codice dell'elenco 1.
Nell'esempio di codice seguente viene creata un'istanza di System.ServiceModel.Channels.CustomBinding e viene aggiunto un elemento System.ServiceModel.Channels.HttpTransportBindingElement all'insieme Element, un insieme di elementi di associazione utilizzati per generare lo stack di canali. Nell'esempio, poiché l'insieme degli elementi presenta solo HttpTransportBindingElement, lo stack di canali risultante dispone solo del canale di trasporto HTTP.
Generazione di un listener di canale.
Dopo avere creato un'associazione, si chiama il metodo System.ServiceModel.Channels.Binding.BuildChannelListener.Uri,System.ServiceModel.Channels.BindingParameterCollection) per generare il listener del canale in cui il parametro di tipo è il canale da creare. In questo esempio si utilizza System.ServiceModel.Channels.IReplyChannel perché si desidera ascoltare i messaggi in arrivo in un modello di scambio di messaggi Request/Reply.
IReplyChannel viene utilizzato per ricevere messaggi di richiesta e restituire messaggi di risposta. La chiamata a System.ServiceModel.Channels.IReplyChannel.ReceiveRequest restituisce un elemento System.ServiceModel.Channels.IRequestChannel, utilizzabile per ricevere il messaggio di richiesta e restituire un messaggio di risposta.
Quando si crea il listener, si passa l'indirizzo di rete su cui è in ascolto, in questo caso https://localhost:8080/channelapp
. In genere, ogni canale del trasporto supporta uno o probabilmente più schemi di indirizzo, ad esempio il trasporto HTTP supporta entrambi gli schemi http e https.
Durante la creazione del listener si passa inoltre un elemento System.ServiceModel.Channels.BindingParameterCollection vuoto. Un parametro dell'associazione è un meccanismo che consente di passare parametri che controllano la modalità di generazione del listener. Poiché nell'esempio questi parametri non vengono utilizzati, viene passato un insieme vuoto.
Ascolto di messaggi in arrivo
Si passa quindi a chiamare System.ServiceModel.ICommunicationObject.Open sul listener e si inizia ad accettare canali. Il comportamento del metodo System.ServiceModel.Channels.IChannelListener.AcceptChannel dipende dalla natura del trasporto, orientato alla connessione o senza connessione. Per trasporti orientati alla connessione, AcceptChannel si blocca fino all'arrivo di una nuova richiesta di connessione, quindi restituisce un nuovo canale che rappresenta la nuova connessione. Per trasporti senza connessione, ad esempio HTTP, AcceptChannel restituisce immediatamente l'unico canale che il listener del trasporto crea.
Nell'esempio il listener restituisce un canale che implementa IReplyChannel. Per ricevere messaggi su questo canale si chiama prima System.ServiceModel.ICommunicationObject.Open sul canale per prepararlo alla comunicazione. Si chiama quindi ReceiveRequest che si blocca fino all'arrivo di un messaggio.
Lettura della richiesta e invio della risposta
Quando ReceiveRequest restituisce un elemento RequestContext, si ottiene il messaggio ricevuto utilizzando la proprietà RequestMessage. Si scrivono l'azione e il contenuto del corpo del messaggio (presumibilmente una stringa).
Per inviare una risposta, si crea un messaggio di risposta, ovvero in questo caso passando i dati di tipo stringa ricevuti nella richiesta. Si chiama quindi Reply per inviare il messaggio di risposta.
Chiusura di oggetti
Per evitare la perdita di risorse, è molto importante chiudere gli oggetti utilizzati nelle comunicazioni quando non sono più necessari. Nell'esempio si chiudono il messaggio di richiesta, il contesto della richiesta, il canale e il listener.
Nell'esempio di codice seguente viene illustrato un servizio di base in cui un listener del canale riceve solo uno messaggio. Un servizio reale continua ad accettare canali e a ricevere messaggi fino alla chiusura del servizio.