Сжатие 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" />
Хотя мне не очень понятно, зачем это нужно.
На всякий случай добавила несколько дополнительных типов пантомимы. Я реализовал 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, которую он предлагает. Также я видел много других реализаций, которые должны заставить это работать, но не могут понять их (например, кодировщик mszn GZip). Зачем мне нужно реализовывать кодировщик или решение кода проекта? Разве IIS не должен заботиться о сжатии?
Так что еще мне нужно сделать, чтобы заставить это работать?
Joni
РЕДАКТИРОВАТЬ: Я думал, что привязки 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: Хорошо для всех в этой загадочной ситуации, у меня есть частичное решение. Т.е. я получил IIS7, чтобы хотя бы сжать мыльные сообщения от службы (хотя теперь я получаю исключение на клиенте, но для этого было опубликовано несколько решений). Проблема была в том, что DynamicCompressionModule не был установлен на моем сервере. "Установить" это фактически для меня означало просто добавить эту строку в раздел applicationHost.config:
<add name="DynamicCompressionModule" image="%windir%\System32\inetsrv\compdyn.dll" />
(Предполагая, что dll существует в этом каталоге, что в моем случае было.) И затем добавление модуля через раздел модулей IIS7 для веб-сайта или сервера.
8 ответов
Попробуйте добавить 'application/soap+xml; charset=utf-8'как динамический тип в applicationHost. Добавление этой части кодировки помогло мне включить сжатие для некоторых ответов JSON из моего обработчика http.
Это в основном тот же ответ, что и @marko, с подробными инструкциями. Это разочаровывающая тема каждый раз, когда я снова к ней обращаюсь, поэтому я хотел обрисовать в общих чертах все, что мне нужно сделать, чтобы это заработало.
Перво-наперво вы захотите использовать.NET 4 на IIS7. Это потому, что только в.NET 4 WCF мог автоматически распаковывать потоки gzip. Подробности этого описаны в разделе " Что нового в WCF 4" (некоторые полезные комментарии в обратной связи).
Мы упростили это при использовании HTTP, позволив клиенту автоматически согласовывать с помощью gzip или дефлировать сжатые потоки, а затем автоматически распаковывать их.
Во-вторых, убедитесь, что вы включили модуль динамического сжатия в IIS. Вам может потребоваться перейти к "Программы и компоненты", чтобы установить его. Убедитесь, что он включен для рассматриваемого веб-приложения - поскольку это не глобальная настройка.
Теперь WPF использует MIME-тип
application/soap+xml; charset=utf-8
для передачи HTTP (по крайней мере, с wsHttpBinding это делает). По умолчанию это НЕ классифицируется как динамический тип, поэтому его необходимо добавить вapplicationHost.config
файл.Просто отредактируйте этот файл на СЕРВЕРЕ: C:\Windows\System32\Inetsrv\Config\applicationHost.config
в
<dynamicTypes>
узел добавить следующую строку (ДО / ЛИНИИ):<add mimeType="application/soap+xml; charset=utf-8" enabled="true" />
Перезагрузите IIS
Теперь у вас должны быть сжатые данные, которые можно проверить в Fiddler.
Я тоже боролся с этим и не мог заставить его работать с моим.svc, хотя это было нормально с файлами.aspx в том же приложении. Оказывается, что он работает только с basicHttpBinding, а не с wsHttpBinding или в двоичном коде customBinding. Это хорошо для меня, поскольку коэффициент сжатия перевешивает преимущества двоичного кодировщика (который значительно уменьшает размер сообщения, но не в 10 раз, что дает сжатие).
Многие люди борются за включение сжатия на уровне 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; charset = 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, даже если вы никогда не просматривали его. папка для начала. Надеюсь, это сэкономит вам много часов скорби.
Просто для кого-то, кто может смотреть в будущее. Мы обновили до Windows 2012 server и IIS 8. Старые mimetypes сжатия конфигурации, которые работали для IIS 7, не работали для IIS 8.
Итак, я попробовал пару предложений здесь, но ничего не получалось. Я просто добавил это к динамическим типам httpcompression: multipart/*
и затем сжатие gzip снова заработало.
Надеюсь, это поможет кому-то еще.
Лучше всего оценить конкретный тип пантомимы, с которым у вас возникли проблемы (например, Fiddler), и убедиться, что он включен в applicationHost.config. Если сжатие установлено и настроено правильно, отслеживание сбоя запроса даст вам знать, что сжатие не было выполнено с расположением "NO_MATCHING_CONTENT_TYPE".
Если кто-то когда-нибудь сталкивался с этим при размещении в Azure в качестве WebApp, вы можете настроить applicationHost.config, используя расширение под названием "IIS Manager", используя портал Azure в разделе "Расширения". Больше информации о самом расширении https://github.com/shibayan/IISManager