在IIS7上托管WCF的GZip压缩

时间:2010-04-26 11:58:51

标签: wcf iis-7 http-compression

每个人,就我而言,问题是在编辑2中的问题。虽然这只是问题的IIS方面的部分解决方案,但它正是我所寻找的。


所以我打算将我的问题添加到关于这个主题的小问题上。

我正在尝试对来自WCF服务的大型soap响应启用GZip压缩。到目前为止,我已按照说明here和其他各种方式在IIS上启用动态压缩。这是applicationHost.config中的dynamicTypes部分:

<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.5Mb),都不会发生压缩。我看过this post,但没有像他描述的那样遇到异常,所以我没有尝试过他提出的CodeProject实现。此外,我已经看到许多其他实现应该让它工作,但无法理解它们(例如,msdn's GZip encoder)。为什么我需要实现编码器或代码项目解决方案? IIS不应该负责压缩吗?

那么我还需要做些什么才能让它发挥作用?

乔尼

编辑: 我认为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至少压缩来自服务的soap消息(虽然我现在在客户端上获得了一个例外,但是为此已经发布了几个解决方案)。 问题是我的服务器上没有安装DynamicCompressionModule。对我来说,实际上“安装”它意味着只需将此行添加到applicationHost.config的部分:

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

(假设dll存在于该目录中,在我的情况下它确实存在。) 然后通过IIS7的模块部分为网站或服务器添加模块。

8 个答案:

答案 0 :(得分:14)

尝试添加'application / soap + xml; charset = utf-8'作为applicationHost中的动态类型。添加这个charset部分帮助我从我的http处理程序启用了一些JSON响应的压缩。

答案 1 :(得分:10)

这与@marko的答案基本相同 - 详细步骤。每次我再次访问时,这都是一个令人沮丧的话题,所以我想概述一下我需要做的一切才能让它发挥作用。

  • 首先,您需要在IIS7上使用.NET 4。这是因为直到.NET 4,WCF才能自动解压缩gzip流。详细信息请参见“Whats new in WCF 4”(反馈中的一些有用的评论)。

      

    我们做了   使用HTTP时更容易   允许客户端自动进行   使用gzip或deflate进行协商   压缩流然后   自动解压缩它们。

  • 其次,确保在IIS中启用了动态压缩模块。您可能需要转到“程序和功能”进行安装。确保您为相关的Web应用程序启用了它 - 因为它不是全局设置。

  • 现在,WPF使用MIME类型application/soap+xml; charset=utf-8进行HTTP传输(至少使用wsHttpBinding)。 默认情况下,这不是动态类型,因此需要将其添加到applicationHost.config文件中。

    只需在服务器上编辑此文件:C:\ Windows \ System32 \ Inetsrv \ Config \ applicationHost.config

    <dynamicTypes>节点中添加以下行(在 / LINE之前):

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

    More on the applicationHost.config file

  • 重新启动IIS

您现在应该拥有压缩数据 - 可以在Fiddler.

中进行验证

答案 2 :(得分:1)

我也一直在努力解决这个问题,并且无法使用我的.svc工作,即使它在同一个应用程序中的.aspx文件也没问题。事实证明它只适用于 basicHttpBinding 而不是 wsHttpBinding 或二进制编码 customBinding 。这对我来说很好,因为压缩因子超过了二进制编码器的好处(它大大减少了消息大小,但不是压缩产生的因子10)。

答案 3 :(得分:0)

最好的办法是评估您遇到问题的特定mime类型(例如Fiddler)并确保将其合并到applicationHost.config中。如果已正确安装和配置压缩,则失败的请求跟踪将告知您未使用“NO_MATCHING_CONTENT_TYPE”处置执行压缩。

答案 4 :(得分:0)

mime类型很可能是Application/octet-stream

答案 5 :(得分:0)

仅限其他可能展望未来的人。我们升级到Windows 2012服务器和IIS 8.用于IIS 7的旧配置压缩mimetypes不适用于IIS 8。

所以,我在这里尝试了一些建议,但没有任何效果。我最后只是将它添加到httpcompression动态类型:multipart/*然后gzip压缩再次工作。

希望这有助于其他人。

答案 6 :(得分:0)

很多人都在努力为WCF服务启用IIS级别压缩。主要是人们正在努力使用wsHttpBinding,如果IIS中启用了动态压缩,basicHttpBinding会立即压缩。我不打算如何启用动态压缩,因为它涵盖了很多不同的帖子,只是搜索&#34; iis压缩应用程序/ soap + xml&#34; 。如前所述,如果您已正确配置所有内容,则应该能够在响应标头中看到使用 Content-Encoding:gzip 压缩的WCF响应。我建议使用Fiddler跟踪您的请求/响应。这是我(任何其他人)使用basicHttpBinding的经验。那么问题就变成为什么它不能与wsHttpBinding一起使用?毫无疑问,您已经读过它了,因为 Content-Type 在这两个绑定之间是不同的。 basicHttpBinding使用 Content-Type:text / xml; charset = utf-8 其中wsHttpBinding使用 Content-Type:application / soap + xml;字符集= UTF-8 即可。前者由dynamicTypes下的默认IIS applicationHost.config设置覆盖。后者不是。您可能已经读过,您需要添加此额外的mimeType并重新启动IIS以解决此问题。这适用于某些人,但对许多人来说并不适用。有些人声称它与wsHttpBinding完全不兼容。这是问题所在。可能有两个 applicationHost.config文件:

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

System32是64位的,是安装IIS时使用的。这也是您已修改为添加额外mimeType的那个,或者您认为的那个!

cannot manually edit applicationhost.config - MUST READ

事实证明,如果使用Notepad ++等32位应用程序,最终修改的是SysWOW64文件夹中的文件。这对你来说是完全透明的。如果您使用常规记事本应用程序,您会注意到您添加的mimeType实际上不在位于System32文件夹中的文件中,它被神奇地添加到SysWOW64文件夹中,即使您正在使用它。从来没有真正浏览过那个文件夹。希望这能为您节省数小时的悲伤。

答案 7 :(得分:0)

如果有人在Azure中作为WebApp托管时偶然遇到这种情况,您可以使用名为&#34; IIS Manager&#34;的扩展来配置applicationHost.config。使用&#34; Extensions&#34;下的azure门户网站。有关扩展程序本身的更多信息https://github.com/shibayan/IISManager