Gestire e ottimizzare messaggi di grandi dimensioni in WCF

di Cristian Civera, in Windows Communication Foundation,

I servizi sviluppati in WCF trovano impiego in moltissimi ambiti che vanno dal semplice REST a servizi full duplex, dato che dispongono di una ampia flessibilità in termini di mezzo di trasporto (il binding). E' facile ricorrere quindi a tale framework qualora si voglia far comunicare classi, processi, macchina o sistemi diversi e in alcuni casi anche per inviare messaggi di grandi dimensioni.

Per messaggo si intende un infoset SOAP XML che oltre all'header porta con sé il body contenente le informazioni specifiche dell'azione, il quale può contenere a sua volta entità serializzate o file binari.

E' bene quindi prestare attenzione ad alcuni parametri da impostare nella configurazione del binding, in primo luogo per rendere funzionante il servizio. Le impostazioni predefinite impediscono infatti la trasmissione di messaggi di dimensioni superiori ai 65.536 byte. E' possibile però cambiare questa impostazione attraverso l'attributo MaxReceivedMessageSize esposto da tutti i binding predefiniti di WCF.

Ecco quindi come impostare questo parametro attraverso il file .config:

<configuration>
  <system.serviceModel>

    <bindings>
      <basicHttpBinding>
        <!-- Massimo 5MB --> 
        <binding name="MyBinding"
                 maxReceivedMessageSize="5242880">
        </binding>
      </basicHttpBinding>
    </bindings>

  </system.serviceModel>

</configuration>

Vi sono inoltre altri fattori controllabili, che vengono racchiusi sotto la proprietà ReaderQuotas, che impongono dei limiti in modo più mirato e sono i seguenti:

  • MaxArrayLength: lunghezza massima degli array (default 16384). Numero che si supera soprattutto quando si usano array di byte;
  • MaxBytesPerRead: numero di byte da leggere per ogni lettura (default 4K). Non è un valore che limita nei messaggi di grandi dimensioni, ma può eventualmente velocizzarne la lettura.
  • MaxDepth: numero di nodi massimi in profondità che si possono leggere (default 32). Questo valore si può superare quando si serializzano entità complesse;
  • MaxNameTableCharCount: numero massimo di caratteri presenti nella tabella di mappatura dei nomi XML (default 16384). Difficilmente si supera questo limite;
  • MaxStringContentLength: lunghezza massima delle stringhe contenute all'interno di un elemento XML (default 8192). Difficilmente si supera questo limite;

Nell'esempio seguente ecco come poter ricevere un array di 20MB:

<binding name="MyBinding">
  <!-- Massimo 20MB -->
  <readerQuotas 
     maxArrayLength="20971520" />
</binding>

E' importante precisare che questa pratica è sconsigliata sia perché sovraccarica il motore di WCF, sia perché aumenta il traffico di rete. In questi casi occorre infatti cambiare strategia come mostrato nello script #57 utilizzando MTOM o la serializzazione binaria.

Infine esiste un ultimo parametro che cambia pesantemente il modo in cui WCF processa il messaggio in entrata: la proprietà TransferMode. Esposta dal netTcp, basicHttp e netNamedPipe permette di passare dalla modalità Buffered (la predefinita) a Streamed e di variare la lettura del messaggio che avviene mentre questo arriva attraverso il cavo senza attendere la completa ricezione(ad eccezione della lettura dell'header).
La tematica è piuttosto complessa e presenta dei limiti, pertanto si invita a leggere la documentazione ufficiale all'indirizzo http://msdn.microsoft.com/en-us/library/ms789010.aspx

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

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

Approfondimenti

Nessuna risorsa collegata

I più letti di oggi