Codificatori personalizzati
In questo argomento verranno illustrate le procedure per creare codificatori personalizzati.
In Windows Communication Foundation (WCF) viene utilizzata un'associazione per specificare la modalità di trasferimento dei dati su una rete tra endpoint. Un'associazione è costituita da una sequenza di elementi di associazione. Un'associazione include elementi di associazione facoltativi del protocollo, quali gli elementi di associazione di protezione, un elemento di associazione di codificatore messaggi obbligatorio e un elemento di associazione di trasporto obbligatorio. Un codificatore di messaggi è rappresentato da un elemento di associazione di codifica dei messaggi. In WCF sono inclusi tre codificatori di messaggi: Binary, MTOM (Message Transmission Optimization Mechanism) e Text.
Un elemento di associazione di codifica dei messaggi serializza un oggetto Message in uscita e lo passa al trasporto oppure riceve dal trasporto il formato serializzato di un messaggio e lo passa al livello protocollo o, se non è presente, all'applicazione.
I codificatori di messaggi trasformano le istanze Message da e in una rappresentazione di trasmissione. Anche se si ritiene che i codificatori risiedano sopra il livello trasporto nello stack del canale, essi risiedono all'interno del livello trasporto. I trasporti (ad esempio HTTP) formattano il messaggio in base ai requisiti dello standard di trasporto. I codificatori (ad esempio Text/XML) si limitano a codificare il messaggio.
Quando si esegue la connessione a un client o server esistente, può non essere possibile scegliere un determinato tipo di codifica dei messaggi. L'accesso ai servizi WCF può tuttavia essere consentito attraverso più endpoint, ognuno con un codificatore di messaggi diverso. Quando un singolo codificatore non include tutti i destinatari del servizio, è consigliabile esporre il servizio su più endpoint. Le applicazioni client potranno quindi scegliere l'endpoint più appropriato. L'utilizzo di più endpoint consente di combinare i vantaggi di differenti codificatori di messaggi con altri elementi di associazione.
Codificatori forniti dal sistema
WCF fornisce un insieme di associazioni di sistema progettate per soddisfare gli scenari di applicazione più comuni. Ognuna di queste associazioni combina un trasporto, un codificatore di messaggi e altre opzioni (ad esempio quelle relative alla protezione). In questo argomento vengono illustrate la procedura per estendere i codificatori di messaggi Text, Binarye MTOM inclusi in WCF e la procedura per creare un codificatore personalizzato. Il codificatore dei messaggi di testo supporta sia la codifica XML semplice che le codifiche SOAP. La modalità di codifica XML semplice del codificatore dei messaggi di testo è denominata POX (Plain Old XML) per distinguerla dalla codifica SOAP basata su testo.
Per ulteriori informazioni sulle combinazioni di elementi di associazione fornite dalle associazioni di sistema, vedere la sezione corrispondente in Scelta di un trasporto.
Come utilizzare i codificatori forniti dal sistema
Una codifica viene aggiunta a un'associazione utilizzando una classe derivata da MessageEncodingBindingElement.
WCF fornisce i tipi di elementi di associazione seguenti derivati dalla classe MessageEncodingBindingElement in grado di supportare la codifica Text, Binary e MTOM (Message Transmission Optimization Mechanism):
- TextMessageEncodingBindingElement: il codificatore più interoperativo, ma il meno efficiente, per i messaggi XML. In genere un servizio Web o un client di servizio Web è in grado di comprendere codice XML in formato testo. La trasmissione di grandi blocchi di dati binari in formato testo non è tuttavia efficiente.
- BinaryMessageEncodingBindingElement: rappresenta l'elemento di associazione che specifica la codifica dei caratteri e la versione dei messaggi utilizzate per i messaggi XML basati su un sistema binario. Si tratta dell'opzione di codifica più efficiente, ma è anche la meno interoperativa in quanto è supportata soltanto da endpoint WCF.
- MTOMMessageEncodingBindingElement: rappresenta l'elemento di associazione che specifica la codifica dei caratteri e la versione dei messaggi utilizzate per una codifica dei messaggi tramite MTOM (Message Transmission Optimization Mechanism). MTOM è una tecnologia efficiente per trasmettere dati binari nei messaggi WCF. Il codificatore MTOM cerca un equilibrio tra efficienza e interoperabilità. La codifica MTOM trasmette la maggior parte del codice XML in formato testo, ma ottimizza grandi blocchi di dati binari trasmettendoli senza introdurre modifiche e senza convertirli in formato testo.
L'elemento di associazione crea una classe MessageEncoderFactorydi tipo Text, Binary o MTOM. La factory crea un'istanza MessageEncoder di tipo Text, Binary o MTOM. In genere è presente una sola istanza. Se tuttavia vengono utilizzate le sessioni, a ogni sessione può essere fornito un codificatore diverso. In questo modo il codificatore dei messaggi in formato binario è in grado di coordinare dizionari dinamici (vedere Infrastruttura XML).
I metodi ReadMessage e WriteMessage rappresentano il nucleo centrale dei codificatori. I metodi consentono la lettura di un messaggio da un flusso o da una matrice Byte. Le matrici di byte vengono utilizzate quando il trasporto viene eseguito in modalità di memorizzazione nel buffer. I messaggi vengono sempre scritti in flussi. Se deve memorizzare il messaggio nel buffer, il trasporto fornisce un flusso che esegue la memorizzazione nel buffer.
Gli altri membri utilizzano contenuto, tipi di supporto e proprietà MessageVersion di supporto. Il trasporto chiama questi metodi di codifica per verificare se il messaggio in ingresso può essere decodificato dal codificatore o per determinare se il messaggio in uscita è valido per questo codificatore.
Ognuna delle tre implementazioni del codificatore aggiunge proprietà attinenti alle codifiche specifiche ed è completamente configurabile. I codificatori espongono inoltre quote di lettore che hanno impostazioni predefinite protette. Per una descrizione delle quote, vedere Infrastruttura XML.
Funzionalità dei codificatori forniti dal sistema
I codificatori di sistema forniscono una serie di funzionalità.
Pooling
Ognuna delle implementazioni del codificatore tenta di eseguire il massimo numero possibile di operazioni pooling. La riduzione delle allocazioni è la misura più comunemente adottata per migliorare le prestazioni del codice gestito. Per eseguire queste operazioni di pooling le implementazioni utilizzano la classe SynchronizedPool. Il file C# contiene una descrizione delle ottimizzazioni aggiuntive utilizzate da questa classe.
Le istanze XmlDictionaryReader e XmlDictionaryWriter vengono inserite nel pool e reinizializzate per impedire l'allocazione di nuove istanze per ogni messaggio. Per i lettori, un callback OnClose richiede il lettore quando viene chiamato Close(). Il codificatore ricicla inoltre alcuni oggetti di stato dei messaggi utilizzati durante la costruzione dei messaggi. Le dimensioni di questi pool sono configurabili mediante le proprietà MaxReadPoolSize e MaxWritePoolSize in ognuna delle tre classi derivata da MessageEncodingBindingElement.
Codifica binaria
Quando la codifica binaria utilizza sessioni, la stringa del dizionario dinamica deve essere comunicata al destinatario del messaggio. Questa operazione viene eseguita anteponendo al messaggio le stringhe del dizionario dinamiche. Il destinatario rimuove le stringhe, le aggiunge alla sessione ed elabora il messaggio. Perché le stringhe del dizionario vengano passate correttamente è necessario che il trasporto venga memorizzato nel buffer.
Le stringhe vengono aggiunte al messaggio da un metodo AddSessionInformationToMessage interno. Questo metodo aggiunge le stringhe in formato UTF-8 davanti al messaggio precedute dalla relativa lunghezza. All'intera intestazione del dizionario viene quindi anteposta la lunghezza dei relativi dati. L'operazione inversa viene eseguita da un metodo ExtractSessionInformationFromMessage interno.
Oltre a elaborare chiavi di dizionario dinamiche, i messaggi con sessione memorizzati nel buffer vengono ricevuti in modo univoco. Anziché creare un lettore sul documento ed elaborarlo, il codificatore binario utilizza la classe MessagePatterns interna per scomporre il flusso binario. L'idea è che la maggior parte dei messaggi ha uno specifico insieme di intestazioni che si presentano in un determinato ordine quando vengono generate da WCF. Il sistema del modello divide in due il messaggio in base a quanto previsto. In caso di esito positivo, inizializza un oggetto MessageHeaders senza analizzare il codice XML. In caso contrario ricorre al metodo standard.
Codifica MTOM
La classe MtomMessageEncodingBindingElement dispone di una proprietà di configurazione aggiuntiva denominata MaxBufferSize. Questa proprietà impone un limite massimo alla quantità di dati che è consentito memorizzare nel buffer durante il processo di lettura di un messaggio. In alcuni casi gli Infoset XML (insiemi di informazioni XML) o altre parti MIME devono essere memorizzati nel buffer per riunire tutte le parti MIME in un unico messaggio.
Per utilizzare correttamente il protocollo HTTP, la classe del codificatore di messaggi MTOM interna fornisce alcune API interne per il metodo GetContentType (interno) e WriteMessage, un metodo pubblico che può essere sottoposto a override. Per garantire che i valori dell'intestazione HTTP concordino con i valori delle intestazioni MIME deve verificarsi un numero maggiore di comunicazioni.
A livello interno il codificatore di messaggi MTOM utilizza visualizzatori di testo di WCF ed è simile al codificatore di messaggi di testo. La differenza principale risiede nel fatto che il codificatore MTOM ottimizza grandi blocchi di oggetti binari o BLOB (Binary Large Object) non convertendoli nella codifica Base 64 prima che vengano integrati nei byte del messaggio. Questi oggetti BLOB rimangono invece estratti e vengono denominati allegati MIME.
Creazione di un codificatore personalizzato
Per implementare un codificatore di messaggi personalizzato, è necessario fornire implementazioni personalizzate delle classi base astratte seguenti:
- MessageEncoder
- MessageEncoderFactory
- MessageEncodingBindingElement
La conversione dalla rappresentazione in memoria di un messaggio a una rappresentazione che può essere scritta in un flusso viene incapsulata all'interno della classe MessageEncoder che funziona come una factory per i lettori e i writer XML che supportano tipi specifici di codifiche XML.
- I metodi principali di questa classe di cui è necessario eseguire l'override sono:
- WriteMessage che accetta un oggetto Message e lo scrive in un oggetto Stream.
- ReadMessage che accetta un oggetto Stream e una dimensione di intestazione massima e restituisce un oggetto Message.
È il codice scritto in questi metodi che gestisce la conversione tra il protocollo di trasporto standard e la codifica personalizzata.
Successivamente sarà necessario codificare una classe factory che crei il codificatore personalizzato. Eseguire l'override di Encoder per restituire un'istanza del codificatore MessageEncoder personalizzato.
Associare quindi il codificatore MessageEncoderFactory personalizzato allo stack dell'elemento di associazione utilizzato per configurare il servizio o il client eseguendo l'override del metodo CreateMessageEncoderFactory per restituire un'istanza di questa factory.
In WCF vengono forniti due esempi che illustrano questo processo utilizzando codice di esempio: Custom Message Encoder: Custom Text Encoder e Custom Message Encoder: Compression Encoder.
Vedere anche
Riferimenti
MessageEncodingBindingElement
MessageEncoderFactory
MessageEncoder
Concetti
Panoramica dell'architettura di trasferimento dei dati
Scelta di un codificatore di messaggi
Scelta di un trasporto