Condividi tramite


Codificatori personalizzati

In questo argomento viene illustrato come creare codificatori personalizzati.

In Windows Communication Foundation (WCF) si usa un binding per specificare come trasferire i dati attraverso una rete tra endpoint. Un'associazione è costituita da una sequenza di elementi di associazione. Un'associazione include elementi facoltativi di associazione del protocollo, ad esempio la sicurezza, un elemento di associazione message encoder 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, Message Transmission Optimization Mechanism (MTOM) e Text.

Un elemento di associazione di codifica dei messaggi serializza un oggetto in uscita Message e lo passa al trasporto oppure riceve la forma serializzata di un messaggio dal trasporto e la passa al livello del protocollo, se presente, o all'applicazione, se non presente.

I codificatori di messaggi trasformano le istanze Message da e verso una rappresentazione di rete. Anche se i codificatori sono descritti come posizionati sopra il livello di trasporto nello stack dei canali, si trovano all'interno del livello di trasporto. I trasporti (ad esempio HTTP) formattano il messaggio in base ai requisiti dello standard di trasporto. I codificatori (ad esempio Text Xml) codificano semplicemente il messaggio.

Quando ci si connette a un client o a un server preesistente, potrebbe non essere possibile scegliere di usare una codifica di messaggi specifica. Tuttavia, i servizi WCF possono essere resi accessibili tramite più endpoint, ognuno con un codificatore di messaggi diverso. Quando un singolo codificatore non copre l'intero gruppo di destinatari per il servizio, è consigliabile esporre il servizio su più endpoint. Le applicazioni client possono quindi scegliere l'endpoint più adatto. L'uso di più endpoint consente di combinare i vantaggi dei diversi codificatori di messaggi con altri elementi di associazione.

codificatori System-Provided

WCF fornisce diverse associazioni fornite dal sistema progettate per coprire gli scenari di applicazione più comuni. Ognuna di queste associazioni combina un trasporto, un codificatore di messaggi e altre opzioni (ad esempio, sicurezza). In questo argomento viene descritto come estendere i codificatori di messaggi Text, Binary e MTOM inclusi in WCF, oppure creare un codificatore personalizzato. Il codificatore di messaggi di testo supporta sia la codifica XML normale che le codifiche SOAP. La modalità di codifica XML normale del codificatore di messaggi di testo viene chiamata codificatore POX ("Plain Old XML") per distinguerla dalla codifica SOAP basata su testo.

Per ulteriori informazioni sulle combinazioni di elementi di associazione forniti dal sistema, vedere la sezione corrispondente in Scelta di un trasporto.

Come usare codificatori System-Provided

Una codifica viene aggiunta a un'associazione usando una classe derivata da MessageEncodingBindingElement.

WCF fornisce i seguenti tipi di elementi di associazione derivati dalla classe MessageEncodingBindingElement, che possono fornire la codifica di testo, binaria e Message Transmission Optimization Mechanism (MTOM).

  • TextMessageEncodingBindingElement: codificatore più interoperabile, ma meno efficiente per i messaggi XML. Un servizio Web o un client del servizio Web può in genere comprendere il codice XML testuale. Tuttavia, la trasmissione di grandi blocchi di dati binari come testo non è efficiente.

  • BinaryMessageEncodingBindingElement: rappresenta l'elemento di associazione che specifica la codifica dei caratteri e il controllo delle versioni dei messaggi utilizzati per i messaggi XML basati su binario. Questa opzione è più efficiente delle opzioni di codifica, ma meno interoperabile, perché è supportata solo dagli endpoint WCF.

  • MtomMessageEncodingBindingElement: rappresenta l'elemento di associazione che specifica la codifica dei caratteri e il controllo delle versioni dei messaggi utilizzati per un messaggio tramite una codifica MTOM (Message Transmission Optimization Mechanism). MTOM è una tecnologia efficiente per la trasmissione di dati binari nei messaggi WCF. Il codificatore MTOM tenta di bilanciare l'efficienza e l'interoperabilità. La codifica MTOM trasmette la maggior parte dei dati XML in formato testuale, ma ottimizza grandi blocchi di dati binari trasmettendoli as-is, senza conversione in testo.

L'elemento di associazione crea un file binario, MTOM o testo MessageEncoderFactory. La fabbrica crea un'istanza binaria, MTOM o di testo MessageEncoderFactory. In genere, è presente una sola istanza. Tuttavia, se vengono usate sessioni, a ogni sessione può essere fornito un codificatore diverso. Il codificatore binario usa questa opzione per coordinare i dizionari dinamici (vedere Infrastruttura XML).

I ReadMessage metodi e WriteMessage sono il nucleo dei codificatori. I metodi forniscono la lettura di un messaggio da un flusso o da una Byte matrice. Le matrici di byte vengono usate quando il trasporto funziona in modalità memorizzata nel buffer. I messaggi vengono sempre scritti nei flussi. Se il trasporto deve mettere il messaggio in buffer, fornisce un flusso per gestire il buffering.

Il resto dei membri lavora con contenuti di assistenza, tipi di media e MessageVersion. Il trasporto chiama questi metodi del codificatore per verificare se il messaggio in arrivo può essere decodificato da esso o per determinare se il messaggio in uscita è valido per questo codificatore.

Ognuna delle tre implementazioni del codificatore aggiunge proprietà rilevanti per le codifiche specifiche ed è completamente configurabile. I codificatori espongono anche quote di lettore con impostazioni predefinite sicure. Per informazioni sulle quote, vedere Infrastruttura XML.

Funzionalità dei codificatori di System-Provided

Esistono diverse funzionalità fornite dai codificatori forniti dal sistema.

Aggregazione

Ognuna delle implementazioni del codificatore cerca di raggruppare il più possibile. La riduzione delle allocazioni è un modo chiave per migliorare le prestazioni del codice gestito. Per realizzare questo pooling, le implementazioni usano la classe SynchronizedPool. Il file C# contiene una descrizione delle ottimizzazioni aggiuntive usate da questa classe.

Le istanze di XmlDictionaryReader e XmlDictionaryWriter vengono messe in pool e reinizializzate per impedire l'allocazione di nuove per ogni messaggio. Per i lettori, un OnClose callback recupera il lettore quando Close() viene chiamato. Il codificatore ricicla anche alcuni oggetti di stato del messaggio usati durante la costruzione di messaggi. Le dimensioni di questi pool sono configurabili dalle proprietà MaxReadPoolSize e MaxWritePoolSize in ognuna delle tre classi derivate da MessageEncodingBindingElement.

Codifica binaria

Quando la codifica binaria usa sessioni, la stringa del dizionario dinamico deve essere comunicata al destinatario del messaggio. A tale scopo, anteporre al messaggio le stringhe del dizionario dinamico. Il ricevitore rimuove le stringhe, le aggiunge alla sessione ed elabora il messaggio. Il passaggio corretto delle stringhe di dizionario richiede che il trasporto venga memorizzato nel buffer.

Le stringhe vengono aggiunte al messaggio da un metodo interno AddSessionInformationToMessage . Aggiunge le stringhe come UTF-8 all'inizio del messaggio, precedute dalla loro lunghezza. L'intera header del dizionario viene quindi preceduta dalla lunghezza del suo dato. L'operazione inversa viene eseguita da un metodo interno ExtractSessionInformationFromMessage .

Oltre all'elaborazione delle chiavi del dizionario dinamico, i messaggi con sessione memorizzati nel buffer vengono ricevuti in modo univoco. Anziché creare un lettore sul documento e elaborarlo, il codificatore binario usa la classe interna MessagePatterns per decostruire il flusso binario. L'idea è che la maggior parte dei messaggi ha un determinato set di intestazioni che vengono visualizzate in un determinato ordine quando generato da WCF. Il sistema di criteri suddivide il messaggio in base a ciò che si aspetta. Se ha esito positivo, inizializza un MessageHeaders oggetto senza analizzare il codice XML. In caso contrario, si fa ricorso al metodo standard.

Codifica MTOM

La MtomMessageEncodingBindingElement classe ha una proprietà di configurazione aggiuntiva denominata MaxBufferSize. In questo modo viene posto un limite superiore sulla quantità di dati che è consentito memorizzare nel buffer durante il processo di lettura di un messaggio. Il set di informazioni XML (Infoset) o altre parti MIME potrebbe dover essere memorizzato nel buffer per riassemblare tutte le parti MIME in un singolo messaggio.

Per funzionare correttamente con HTTP, la classe del codificatore messaggi MTOM interno fornisce alcune API interne per GetContentType (che è anche interno) e WriteMessage, che è pubblico e può essere sottoposto a override. È necessario che si verifichi una maggiore comunicazione per garantire che i valori nelle intestazioni HTTP siano d'accordo con i valori nelle intestazioni MIME.

Internamente, il codificatore di messaggi MTOM usa i lettori di testo di WCF ed è simile al codificatore di testo. La differenza principale è che ottimizza blocchi di grandi dimensioni di file binari o "oggetti binari di grandi dimensioni" (BLOB), non convertendoli in codifica Base 64 prima di essere incorporati nei byte del messaggio. Questi BLOB vengono invece estratti e a cui viene fatto riferimento come allegati MIME.

Scrittura di un codificatore personalizzato

Per implementare il proprio codificatore di messaggi personalizzato, è necessario fornire implementazioni personalizzate delle classi di base astratte seguenti:

La conversione dalla rappresentazione in memoria di un messaggio a una rappresentazione che può essere scritta in un flusso viene incapsulata all'interno della MessageEncoder classe , che funge da factory per lettori XML e writer XML che supportano tipi specifici di codifiche XML.

È il codice scritto in questi metodi che gestisce la conversione tra il protocollo di trasporto standard e la codifica personalizzata.

Successivamente è necessario scrivere il codice di una classe factory che crea il codificatore personalizzato. Esegui l'override di Encoder per restituire un'istanza del tuo MessageEncoder personalizzato.

Connettere quindi il componente personalizzato MessageEncoderFactory allo stack di elementi di associazione usato per configurare il servizio o il client eseguendo l'override del metodo CreateMessageEncoderFactory per restituire un'istanza di questa factory.

Con WCF sono disponibili due esempi che illustrano questo processo con codice di esempio: Codificatore messaggi personalizzato: Codificatore di testo personalizzato e Codificatore di messaggi personalizzato: Codificatore di compressione.

Vedere anche