¿Cuál es la forma más fácil de agregar compresión a WCF en Silverlight?
compression gzip (4)
Tengo una aplicación Silverlight 2 beta 2 que accede a un servicio web de WCF. Debido a esto, actualmente solo puede usar enlaces básicos de HTTP. El servicio web devolverá cantidades bastante grandes de datos XML. Esto parece bastante derrochador desde el punto de vista del uso del ancho de banda ya que la respuesta, si está comprimida, sería más pequeña por un factor de 5 (de hecho pegué la respuesta en un archivo txt y lo comprimí).
La solicitud tiene el mensaje "Aceptar codificación: gzip, desinflar". ¿Hay alguna manera de que el servicio WCF gzip (o de otra forma comprima) la respuesta?
Encontré este link pero parece un poco complejo para la funcionalidad que debería manejarse en mi humilde opinión.
OK - al principio marqué la solución usando System.IO.Compression como la respuesta porque nunca podría "parecer" que la compresión dinámica IIS7 funcionara. Bueno, como resultado:
Compresión dinámica en IIS7 funcionaba todo el tiempo. Es solo que el complemento Web Developer Helper de Nikhil para IE no lo mostró funcionando. Supongo que, dado que SL entrega el servicio web al navegador, que el navegador lo maneja "bajo las sábanas" y la herramienta de Nikhil nunca ve la respuesta comprimida. Pude confirmar esto mediante el uso de Fiddler, que monitorea el tráfico externo a la aplicación del navegador. En fiddler, la respuesta fue, de hecho, comprimida gzip !!
El otro problema con la solución System.IO.Compression es que System.IO.Compression no existe en Silverlight CLR.
Por lo tanto, desde mi punto de vista, la forma MÁS FÁCIL de habilitar la compresión WCF en Silverlight es habilitar la compresión dinámica en IIS7 y no escribir ningún código.
No vi una forma nativa para que WCF hiciera la compresión al hacer un proyecto de WCF recientemente. Acabo de utilizar el espacio de nombres System.IO.Compression e hice un compresor rápido. Aquí está el código que utilicé
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;
}
}
entonces solo hice que mis servicios tomaran una matriz de bytes como entrada, como tal
void ReceiveData(byte[] data);
Funcionó bien para mí
Si está utilizando IIS7, eche un vistazo al Módulo de compresión . Esto le permite configurar la compresión de las solicitudes HTTP a su servidor.
También se debe tener en cuenta que es posible que necesite agregar el tipo mime a applicationHost.config
sección <httpCompression><dynamicTypes>
además de habilitar la compresión para el sitio:
<add mimeType="application/soap+msbin1" enabled="true" />
Si ciertas respuestas dinámicas no se están comprimiendo (y algunas lo están) podría ser un problema de tipo MIME. Use Fiddler para obtener los detalles asociados con la solicitud. El seguimiento de solicitudes fallidas puede ser útil para determinar si IIS incluso está intentando comprimir la respuesta. Si la compresión está configurada correctamente, verá un NO_MATCHING_CONTENT_TYPE
en la sección de rastreo completa de la salida de rastreo.
WS-Compression para WCF le permite configurar la compresión en el enlace.
Ver WS-Compression para WCF por Pablo M. Cibraro
Alternativamente, pruebe con Microsofts GZip Encoder Sample que "crea un canal codificador que usa la clase System.IO.Compression.GZipStream para comprimir los mensajes WCF salientes"