Как проще всего добавить сжатие в WCF в Silverlight?

У меня есть приложение Silverlight 2 beta 2, которое обращается к веб-службе WCF. Из-за этого в настоящее время он может использовать только привязку basicHttp. Webservice будет возвращать довольно большие объемы XML-данных. Это кажется довольно расточительным с точки зрения использования полосы пропускания, так как ответ, если его сжать, будет меньше в 5 раз (я фактически вставил ответ в txt-файл и сжал его.).

Запрос имеет «Accept-Encoding: gzip, deflate» — есть ли какой-либо способ иметь службу WCF gzip (или иным образом сжимать) ответ?

Я нашел эту ссылку, но она кажется немного сложной для функциональности, которая должна быть обработана из коробки IMHO.

OK-сначала я отметил решение с помощью системы.IO.Сжатие как ответ, как я никогда не мог «казаться», чтобы получить IIS7 динамическое сжатие работать. Ну, как оказалось:

  1. Динамическое сжатие на IIS7 работало Al along. Просто плагин Nikhil Web Developer Helper для IE не показал, что он работает. Я предполагаю, что, поскольку SL передает вызов веб-службы браузеру, браузер обрабатывает его «под крышками», и инструмент Nikhil никогда не видит сжатый ответ. Я смог подтвердить это с помощью Fiddler, который отслеживает трафик, внешний к браузерному приложению. В fiddler ответ был, по сути, сжатым gzip!!

  2. Другая проблема с системой.IO.Решение сжатия-это та система.IO.Сжатие не существует в Silverlight CLR.

Поэтому, с моей точки зрения, самый простой способ включить сжатие WCF в Silverlight-это включить динамическое сжатие в IIS7 и вообще не писать код.

4 ответа

  1. Я не видел собственного способа для WCF, чтобы сделать сжатие при выполнении проекта WCF недавно. Я просто использовал систему.IO.Сжатие пространства имен и быстрый компрессор. Вот код, который я использовал

    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. WS-Compression for WCF позволяет настроить сжатие для привязки.

    См. WS-Compression for WCF от Pablo M. Cibraro

    В качестве альтернативы попробуйте пример кодировщика Microsofts GZip ,который » создает канал кодировщика, использующий систему.IO.Сжатие.Класс GZipStream для сжатия исходящих сообщений WCF»

  3. Следует также отметить, что вам может потребоваться добавить тип mime applicationHost.config<httpCompression><dynamicTypes>в раздел under в дополнение к включению сжатия для сайта:

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

    Если определенные динамические ответы не сжимаются (а некоторые сжимаются), это может быть проблема типа mime. Используйте Fiddler для получения сведений, связанных с запросом. Ошибка трассировки запроса может быть полезна при определении того, пытается ли IIS вообще сжимать ответ. Если сжатие настроено правильно, вы увидите a NO_MATCHING_CONTENT_TYPEв разделе полная трассировка выходных данных трассировки.