在Silverlight中向WCF添加压缩的最简单方法是什么?

时间:2008-08-13 16:08:44

标签: wcf silverlight compression gzip

我有一个访问WCF Web服务的silverlight 2 beta 2应用程序。因此,它目前只能使用basicHttp绑定。 Web服务将返回相当大量的XML数据。从带宽使用的角度来看,这看起来相当浪费,因为如果压缩,响应会小5倍(我实际上将响应粘贴到txt文件中并压缩它。)。

请求确实有“Accept-Encoding:gzip,deflate” - 有没有办法让WCF服务gzip(或以其他方式压缩)响应?

我确实找到了这个link但是对于应该在开箱即用的恕我直言中处理的功能来说确实有点复杂。

好的 - 首先我使用System.IO.Compression标记解决方案作为答案,因为我无法“看起来”让IIS7动态压缩工作。事实证明:

  1. IIS7上的动态压缩 正在进行中。只是Nikhil的IE开发人员Helper插件没有显示它的工作原理。我的猜测是,由于SL将Web服务调用关闭到浏览器,浏览器“在幕后”处理它,而Nikhil的工具永远不会看到压缩响应。我能够通过使用Fiddler来确认这一点,Fiddler监视浏览器应用程序外部的流量。事实上,在提琴手中,响应是gzip压缩!!

  2. System.IO.Compression解决方案的另一个问题是Silverlight CLR中不存在System.IO.Compression。

  3. 因此,从我的角度来看,在Silverlight中启用WCF压缩的EASIEST方法是在IIS7中启用动态压缩,并且根本不编写代码。

4 个答案:

答案 0 :(得分:12)

WCF的WS-Compression允许您在绑定上配置压缩。

见Pablo M. Cibraro的WS-Compression for WCF

或者,尝试使用Microsofts GZip Encoder Sample“创建一个使用System.IO.Compression.GZipStream类压缩传出WCF消息的编码器通道”

答案 1 :(得分:11)

我最近在做WCF项目时没有看到WCF进行压缩的本地方式。我刚刚使用了System.IO.Compression命名空间并制作了一个快速压缩器。这是我使用的代码

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;
    }
}

然后我让我的服务接受一个字节数组作为输入,就像这样

void ReceiveData(byte[] data);

为我做好了。

答案 2 :(得分:10)

如果您使用的是IIS7,请查看Compression Module。这允许您为服务器的HTTP请求配置压缩。

答案 3 :(得分:3)

还应注意,除了为网站启用压缩之外,您可能还需要将{mime类型添加到applicationHost.config部分下的<httpCompression><dynamicTypes>

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

如果某些动态响应未被压缩(有些是动态响应),则可能是mime类型问题。使用Fiddler获取与请求关联的细节。失败的请求跟踪可能有助于确定IIS是否甚至试图压缩响应。如果正确配置压缩,您将在跟踪输出的完整跟踪部分中看到NO_MATCHING_CONTENT_TYPE