Подтвердить что ты не робот

Сжатие GZip с помощью WCF, размещенного на IIS7

Всем, насколько мне известно, вопрос решен в EDIT 2. Хотя это лишь частичное решение проблемы IIS проблемы, это то, что я искал.


Итак, я собираюсь добавить свой вопрос к маленькому океану вопросов по этому вопросу.

Я пытаюсь включить сжатие GZip на большие ответы на мыло из службы WCF. До сих пор я следил за инструкциями здесь и в других местах, чтобы включить динамическое сжатие в IIS. Здесь мой раздел dynamicTypes из applicationHost.config:

<dynamicTypes>
    <add mimeType="text/*" enabled="true" />
    <add mimeType="message/*" enabled="true" />
    <add mimeType="application/x-javascript" enabled="true" />
    <add mimeType="application/atom+xml" enabled="true" />
    <add mimeType="application/xaml+xml" enabled="true" />
    <add mimeType="application/xop+xml" enabled="true" />
    <add mimeType="application/soap+xml" enabled="true" />
    <add mimeType="*/*" enabled="false" />
</dynamicTypes>

А также:

<urlCompression doDynamicCompression="true" doStaticCompression="true" />

Хотя я не очень понимаю, зачем это нужно.

Наброси несколько лишних типов mime на всякий случай. Я применил IClientMessageInspector для добавления Accept-Encoding: gzip, deflate для моего клиента HttpRequests. Вот пример заголовка запроса, взятого из fiddler:

POST http://[omitted]/TestMtomService/TextService.svc HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8
Accept-Encoding: gzip, deflate
Host: [omitted]
Content-Length: 542
Expect: 100-continue

Теперь это не работает. Просто нет сжатия, независимо от размера сообщения (до 1,5 Мб). Я просмотрел этот пост, но не столкнулся с тем исключением, которое он описывает, поэтому я не пробовал реализацию CodeProject, которую он предлагает. Также я видел много других реализаций, которые должны заставить это работать, но не могут их понять (например, msdn GZip encoder). Зачем мне нужно реализовать кодировщик или решение для кода? Не следует ли IIS следить за сжатием?

Итак, что еще мне нужно сделать, чтобы заставить это работать?

Джони

EDIT: Я думал, что привязки WCF могут стоить публикации, хотя я не уверен, что они релевантные (это от клиента):

<system.serviceModel>
<bindings>
    <wsHttpBinding>
    <binding name="WsTextBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
      receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
      transactionFlow="false" hostNameComparisonMode="StrongWildcard"
      maxBufferPoolSize="5000000" maxReceivedMessageSize="5000000"
      messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
      allowCookies="false">
      <readerQuotas maxDepth="32" maxStringContentLength="5000000"
        maxArrayLength="5000000" maxBytesPerRead="5000000" maxNameTableCharCount="5000000" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00"
        enabled="false" />
      <security mode="None">
        <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
        <message clientCredentialType="None" negotiateServiceCredential="false"
          algorithmSuite="Default" establishSecurityContext="false" />
      </security>
<client>
  <endpoint address="http://[omitted]/TestMtomService/TextService.svc"
   binding="wsHttpBinding" bindingConfiguration="WsTextBinding" behaviorConfiguration="GzipCompressionBehavior"
   contract="TestMtomModel.ICustomerService" name="WsTextEndpoint">
  </endpoint>
</client>
<behaviors>
  <endpointBehaviors>
    <behavior name="GzipCompressionBehavior">
      <gzipCompression />
    </behavior>
  </endpointBehaviors>
</behaviors>
<extensions>
  <behaviorExtensions>
    <add name="gzipCompression"
         type="TestMtomModel.Behavior.GzipCompressionBehaviorExtensionElement, TestMtomModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  </behaviorExtensions>
</extensions>
    </binding>
  </wsHttpBinding>
</bindings>

ИЗМЕНИТЬ 2: Ну, для кого-либо еще в этой таинственной ситуации, у меня есть частичное решение. I.e., я получил IIS7, по крайней мере, сжимаю мыльные сообщения от службы (хотя теперь я получаю исключение на клиенте, но для этого было опубликовано несколько решений). Проблема заключалась в том, что DynamicCompressionModule не был установлен на моем сервере. "Установка" на самом деле для меня означала просто добавление этой строки в раздел applicationHost.config:

<add name="DynamicCompressionModule" image="%windir%\System32\inetsrv\compdyn.dll" />

(Предполагая, что dll существует в этом каталоге, что в моем случае это было.) Затем добавьте модуль через раздел модулей IIS7 для веб-сайта или сервера.

4b9b3361

Ответ 1

Попробуйте добавить 'application/soap + xml; charset = utf-8 'как динамический тип в applicationHost. Добавление этой части charset помогло мне включить сжатие для некоторых ответов JSON от моего обработчика http.

Ответ 2

Это в основном тот же ответ, что и @marko - с подробными шагами. Это неутешительная тема каждый раз, когда я пересматриваю ее, поэтому я хотел бы изложить все, что мне нужно сделать, чтобы заставить ее работать.

  • Прежде всего, вы захотите использовать .NET 4 на IIS7. Это связано с тем, что только .NET 4 WCF мог автоматически распаковывать потоки gzip. Подробности этого описаны в Что нового в WCF 4 '(некоторые полезные комментарии в отзывах).

    Мы сделали это проще при использовании HTTP посредством позволяя клиенту автоматически вести переговоры с помощью gzip или deflate сжатые потоки, а затем автоматически распаковывать их.

  • Во-вторых, убедитесь, что вы включили модуль динамической компрессии в IIS. Вам может потребоваться перейти в "Программы и функции", чтобы установить его. Убедитесь, что он включен для рассматриваемого веб-приложения - поскольку это не глобальная настройка.

  • Теперь WPF использует тип MIME application/soap+xml; charset=utf-8 для передачи HTTP (по крайней мере, с помощью wsHttpBinding). По умолчанию это НЕ классифицируется как динамический тип, поэтому его необходимо добавить в файл applicationHost.config.

    Просто отредактируйте этот файл на сервере: C:\Windows\System32\Inetsrv\Config\applicationHost.config

    В <dynamicTypes> node добавьте следующую строку (ПЕРЕД А/ЛИНИЕЙ):

    <add mimeType="application/soap+xml; charset=utf-8" enabled="true" />
    

    Подробнее о файле applicationHost.config

  • Перезапустите IIS

Теперь вы должны иметь сжатые данные, которые могут быть проверены в Fiddler.

Ответ 3

Я тоже борюсь с этим и не мог заставить его работать с моим .svc, даже если это было хорошо с .aspx файлами в одном приложении. Оказывается, что он работает только с basicHttpBinding, а не wsHttpBinding или двоичным кодированным customBinding. Это хорошо для меня, поскольку коэффициент сжатия превосходит преимущество двоичного кодировщика (что уменьшает размер сообщения довольно много, но не фактор 10, который дает компрессия).

Ответ 4

Лучше всего оценить конкретный тип mime, с которым вы столкнулись (например, Fiddler), и убедиться, что он включен в applicationHost.config. Если сжатие установлено и настроено правильно, неудачная трассировка запроса позволит вам знать, что сжатие не выполнялось с помощью "NO_MATCHING_CONTENT_TYPE".

Ответ 5

Тип мим скорее всего Application/octet-stream

Ответ 6

Просто для кого-то, кто может смотреть в будущем. Мы перешли на сервер Windows 2012 и IIS 8. Старые сценарии сжатия сценариев, которые работали для IIS 7, не работали для IIS 8.

Итак, я попробовал пару предложений здесь, но ничего не получилось. Я закончил тем, что просто добавил это в httpcompression dynamictypes: multipart/*, а затем сжатие gzip снова работало.

Надеюсь, это поможет кому-то еще.

Ответ 7

Многие люди борются с включением сжатия уровня IIS для служб WCF. В основном люди борются с wsHttpBinding, где basicHttpBinding сжимается из коробки, если динамическое сжатие включено в IIS. Я не собираюсь рассказывать о том, как включить динамическое сжатие, потому что оно охватывает множество разных сообщений, просто найдите "приложение сжатия iis/soap + xml" . Как было сказано ранее, если вы все правильно настроили, вы должны увидеть ответы WCF, сжатые в Content-Encoding: gzip в заголовке ответа. Я предлагаю использовать Fiddler для отслеживания вашего запроса/ответа. Это был мой (любой другой) опыт с basicHttpBinding. Тогда возникает вопрос, почему он не работает с wsHttpBinding? Несомненно, вы уже прочитали это, потому что Content-Type отличается от этих двух привязок. basicHttpBinding использует Content-Type: text/xml; charset = utf-8, где wsHttpBinding использует Content-Type: application/soap + xml; кодировка = UTF-8. Первый охватывает настройку по умолчанию IIS applicationHost.config в dynamicTypes. Последнее не так. Вероятно, вы прочитали, что вам нужно добавить этот дополнительный mimeType и перезапустить IIS, чтобы исправить это. Это работает для некоторых людей, однако это не для многих. Некоторые заявляют, что он просто несовместим с wsHttpBinding. Вот проблема. Существуют потенциально два файла applicationHost.config:

C:\Windows\System32\inetsrv\config
C:\Windows\SysWOW64\inetsrv\Config

System32 - это 64-разрядный, и он используется при установке IIS. Это также тот, который вы изменили, чтобы добавить дополнительный mimeType, или, как вы думали!

не может вручную редактировать applicationhost.config - ДОЛЖНО ПРОЧИТАТЬ

Как оказалось, если вы используете 32-битное приложение, такое как Notepad ++, то, что вы в конечном итоге изменяете, является файлом в папке SysWOW64. Это совершенно прозрачно для вас. Если вы используете обычное приложение "Блокнот", вы заметите, что добавленный вами mimeType на самом деле не находится в файле, который находится в папке System32, он был волшебным образом добавлен в папку SysWOW64, даже если вы никогда не просматривали этот файл для начала. Надеюсь, это сэкономит вам много часов горя.

Ответ 8

Если кто-либо наткнется на это при размещении в Azure как WebApp, вы можете настроить applicationHost.config с помощью расширения, называемого "Диспетчер IIS", используя портал azure в разделе "Расширения". Дополнительная информация о самом расширении https://github.com/shibayan/IISManager