2008-08-13 20 views
23

Ho un Silverlight 2 Beta 2 applicazione che accede a un servizio Web WCF. Per questo motivo, al momento può utilizzare solo l'associazione Http di base. Il servizio web restituirà quantità piuttosto elevate di dati XML. Questo sembra abbastanza dispendioso dal punto di vista utilizzo di banda come la risposta, se compresso, sarebbe inferiore di un fattore 5 (in realtà ho incollato la risposta in un file txt e zippato esso.).Qual è il modo più semplice per aggiungere la compressione a WCF in Silverlight?

La richiesta ha il "Accept-Encoding: gzip, deflate" - C'è un modo in cui il servizio WCF gzip (o altrimenti comprime) la risposta?

ho trovato questo link ma sembra certo un po 'complessa per la funzionalità che deve essere maneggiato out-of-the-box IMHO.

OK - in un primo momento mi ha segnato la soluzione utilizzando lo System.IO.Compression come la risposta che ho potuto mai "sembrare" per ottenere la compressione dinamica IIS7 per lavorare. Beh, a quanto pare:

  1. Dynamic Compression su IIS7 era lavorando al lungo. E 'solo che il plug-in di Web Developer Helper di Nikhil per IE non lo ha dimostrato funzionante. La mia ipotesi è che, poiché le mani SL chiamata al servizio Web via al browser, che il browser gestisce "sotto le coperte" e strumento di Nikhil non vede mai la risposta compressa. Sono stato in grado di confermare questo utilizzando Fiddler che monitora il traffico esterno all'applicazione browser. In violinista, la risposta è stata, infatti, compresso gzip !!

  2. L'altro problema con la soluzione System.IO.Compression è che System.IO.Compression non esiste nel Silverlight CLR.

Quindi, dal mio punto di vista, il modo più semplice per abilitare la compressione WCF in Silverlight è quello di consentire dinamica di compressione in IIS7 e scrivere alcun codice a tutti.

+0

La compressione dinamica funziona solo per alcune richieste (ad esempio quelle ritenute da IIS come spesso chiamate). quindi è una bella funzionalità ma non ne hai il controllo. Ho una chiamata molto grande quando un utente effettua l'accesso. Ma succede come una volta al giorno. e non è compresso. –

risposta

10

Se si utilizza IIS7, dare un'occhiata allo Compression Module. Questo ti consente di configurare la compressione per le richieste HTTP sul tuo server.

+0

Alcune avvertenze qui: il mio proxy di lavoro rimuove l'intestazione gzip di accettazione (wtf, giusto?). E stai solo comprimendo i dati che vanno al cliente. – russau

11

Non ho visto un modo nativo per WCF di fare compressione quando si fa un progetto WCF di recente. Ho appena usato lo spazio dei nomi System.IO.Compression e fatto un rapido compressore. Ecco il codice che ho usato

public static class CompressedSerializer 
{ 
    /// <summary> 
    /// Decompresses the specified compressed data. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="compressedData">The compressed data.</param> 
    /// <returns></returns> 
    public static T Decompress<T>(byte[] compressedData) where T : class 
    { 
     T result = null; 
     using (MemoryStream memory = new MemoryStream()) 
     { 
      memory.Write(compressedData, 0, compressedData.Length); 
      memory.Position = 0L; 

      using (GZipStream zip= new GZipStream(memory, CompressionMode.Decompress, true)) 
      { 
       zip.Flush(); 
       var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 
       result = formatter.Deserialize(zip) as T; 
      } 
     } 

     return result; 
    } 

    /// <summary> 
    /// Compresses the specified data. 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="data">The data.</param> 
    /// <returns></returns> 
    public static byte[] Compress<T>(T data) 
    { 
     byte[] result = null; 
     using (MemoryStream memory = new MemoryStream()) 
     { 
      using (GZipStream zip= new GZipStream(memory, CompressionMode.Compress, true)) 
      { 
       var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 
       formatter.Serialize(zip, data); 
      } 

      result = memory.ToArray(); 
     } 

     return result; 
    } 
} 

poi ho avuto i miei servizi prendono in un array di byte come input, come ad esempio

void ReceiveData(byte[] data); 

funzionato bene per me.

+1

Nota che GZipStream non è disponibile nel CLR Silverlight 2. DimeBrain ha e implementazione di SharpZipLib qui: http://dimebrain.com/2008/06/compression-i-l.html – russau

12

WS-compressione per WCF consente di configurare la compressione sul legame.

Vedi WS-Compression for WCF di Pablo M. Cibraro

In alternativa, provate Microsofts GZip Encoder Sample che "crea un canale encoder che utilizza lo System.IO.Compression.Classe GZipStream per comprimere in uscita messaggi WCF"

+3

L'unico avvertimento è che Silverlight 2 non supporta affatto i collegamenti WS, solo i collegamenti BasicHttp. – caryden

3

Si deve anche notare che potrebbe essere necessario per aggiungere il tipo MIME per applicationHost.config sotto <httpCompression><dynamicTypes> sezione oltre a consentire la compressione per il sito:

<add mimeType="application/soap+msbin1" enabled="true" /> 

Se certa dinamica le risposte non vengono compresse (e alcune lo sono) potrebbe essere un problema di tipo mime.Usare Fiddler per ottenere le specifiche associate alla richiesta.La traccia delle richieste non riuscite può essere utile per determinare se IIS sta tentando di comprimere la risposta o meno. la compressione è configurata correttamente vedrete un NO_MATCHING_CONTENT_TYPE nella traccia completa sezione dell'output di traccia.

+0

Questo lo ha fatto per me. Tuttavia, occorre notare che è necessario impostare questa impostazione nel file C: \ Windows \ System32 \ inetsrv \ config \ applicationHost.config perché l'impostazione web.config viene ignorata. Ho lavorato subito dopo averlo cambiato. – R4cOON