Am o aplicație Silverlight 2 beta 2 care accesează un serviciu Web WCF. Din acest motiv, în prezent, se poate utiliza numai legarea basicHttp. Serviciul web va returna cantități destul de mari de date XML. Acest lucru pare destul de risipitor din punct de vedere al utilizării lățimii de bandă, deoarece răspunsul, dacă este zip, ar fi mai mic cu un factor de 5 (de fapt, am lipit răspunsul într-un fișier txt și l-am prins).
Cererea are "Accept-Encoding: gzip, deflate" - Există vreo modalitate prin care serviciul WCF gzip (sau altfel comprima) răspunsul?
Am găsit acest link , dar sigur pare un pic cam complex pentru funcționalitatea care ar trebui să fie gestionată în afara casetei IMHO.
OK - la inceput am marcat solutia folosind System.IO.Compression ca raspuns ca niciodata nu mi-ar fi "parut" sa fac compresia dinamica IIS7 sa functioneze. Ei bine, după cum se dovedește:
Compresia dinamică pe IIS7 a fost de lucru de-a lungul. Doar pluginul Web Developer Helper al lui Nikhil pentru IE nu a arătat că funcționează. Cred că din moment ce SL difuzează serviciul web în browser, browser-ul se ocupă de el "sub capace", iar instrumentul lui Nikhil nu vede niciodată răspunsul comprimat. Am reușit să confirm acest lucru prin utilizarea programului Fiddler care monitorizează traficul extern aplicației de browser. În glumă, răspunsul a fost, de fapt, comprimat cu gzip!
Cealaltă problemă cu soluția System.IO.Compression este că System.IO.Compression nu există în Silverlight CLR.
Deci, din perspectiva mea, modul EASIEST de a permite compresia WCF în Silverlight este de a permite comprimarea dinamică în IIS7 și de a nu scrie deloc codul.
Nu am văzut un mod nativ pentru WCF de a face compresie atunci când a făcut un proiect WCF recent. Tocmai am folosit spațiul de nume System.IO.Compression și am făcut un compresor rapid. Iată codul pe care l-am folosit
public static class CompressedSerializer
{
///
/// Decompresses the specified compressed data.
///
///
/// The compressed data.
///
public static T Decompress(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;
}
///
/// Compresses the specified data.
///
///
/// The data.
///
public static byte[] Compress(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;
}
}
atunci am avut doar serviciile mele ia într-o matrice de octeți ca o intrare, ca atare
void ReceiveData(byte[] data);
Am lucrat bine pentru mine.
Dacă utilizați IIS7, aruncați o privire la Modul de comprimare . Aceasta vă permite să configurați compresia pentru cererile HTTP către serverul dvs.
WS-Compression pentru WCF vă permite să configurați compresia pe legare.
Consultați WS-Compression for WCF de Pablo M. Cibraro
Alternativ, încercați Microsoft GZip Encoder Example care "creează un canal de codificator care utilizează clasa System.IO.Compression.GZipStream pentru a comprima mesajele WCF de ieșire "
It should also be noted that you may need to add the mime type to applicationHost.config
under
section in addition to enabling compression for the site:
Dacă anumite răspunsuri dinamice nu sunt comprimate (și unele sunt) ar putea fi o problemă de tip mime. Utilizați Fiddler pentru a obține specificul asociat cererii. Trasarea nereușită a solicitărilor poate fi utilă pentru a determina dacă IIS încearcă sau nu să comprime răspunsul. Dacă compresia este corect configurată, veți vedea NO_MATCHING_CONTENT_TYPE
în secțiunea completare urmărire a traseului.