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

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

What is the easiest way to add compression to WCF in Silverlight?

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

该请求确实具有" Accept-Encoding:gzip,deflate "-是否可以通过任何方式使WCF服务gzip(或以其他方式压缩)响应?

我确实找到了此链接,但是对于应该立即使用的恕我直言的功能,看来确实有点复杂。

好吧-最初,我使用System.IO.Compression作为答案标记了解决方案,因为我永远无法"似乎"使IIS7动态压缩正常工作。好吧,事实证明:

  • IIS7上的动态压缩一直在进行。仅仅是Nikhil的IE的Web Developer Helper插件没有显示出它的作用。我的猜测是,由于SL将Web服务调用交给浏览器,因此浏览器"在幕后"进行处理,而Nikhil的工具从不看到压缩的响应。我能够通过使用Fiddler来确认这一点,它监视浏览器应用程序外部的流量。在提琴手中,响应实际上是gzip压缩了!!

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

  • 因此,从我的angular来看,在Silverlight中启用WCF压缩的最简单方法是在IIS7中启用动态压缩,并且完全不编写任何代码。


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

    请参阅Pablo M.Cibraro的WS-Compression for WCF

    或者,尝试使用Microsoft的GZip编码器示例,该示例"创建使用System.IO.Compression.GZipStream类来压缩传出WCF消息的编码器通道"


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    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;
        }
    }

    然后我只是让我的服务将字节数组作为输入,就像这样的

    1
    void ReceiveData(byte[] data);

    对我来说很好。


    如果使用IIS7,请查看压缩模块。这使您可以配置对服务器的HTTP请求的压缩。


    还应注意,除了对站点启用压缩之外,您可能还需要在<httpCompression><dynamicTypes>部分下的applicationHost.config中添加mime类型:

    1
     

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


    推荐阅读