代码之家  ›  专栏  ›  技术社区  ›  joniba

IIS7上承载WCF的GZip压缩

  •  24
  • joniba  · 技术社区  · 15 年前

    各位,就我而言,这个问题在编辑2中得到了解答。虽然这只是问题IIS方面的部分解决方案,但这正是我所寻找的。


    因此,我将把我的问题添加到这个问题的小海洋中。

    我试图对来自WCF服务的大型soap响应启用GZip压缩。到目前为止,我遵循了指示 here 并在各种其他地方启用IIS上的动态压缩。这是applicationHost中的“我的动态类型”部分。配置:

    <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编码: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消息(虽然我现在在客户端上遇到了一个异常,但已经发布了几个解决方案)。 问题是我的服务器上没有安装DynamicPressionModule。对我来说,“安装”它实际上意味着简单地将这一行添加到applicationHost。配置部分:

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

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

    8 回复  |  直到 8 年前
        1
  •  14
  •   Marko    15 年前

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

        2
  •  10
  •   Simon_Weaver    10 年前

    这与@marko的答案基本相同——有详细的步骤。这是一个令人沮丧的话题,每次我重温它,所以我想概述我需要做的一切,以使其工作。

    • 你首先要使用的东西。IIS7的第四名。这是因为直到。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。配置

      <dynamicTypes> 节点添加以下行(在 / 行):

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

      More on the applicationHost.config file

    • 重新启动IIS

    你现在应该有压缩数据了——可以在 Fiddler.

        3
  •  1
  •   mackie    14 年前

    我也一直在努力解决这个问题,但无法让它与我的电脑配合使用。svc,尽管这对我来说很好。同一应用程序中的aspx文件。事实证明,它只适用于 基本绑定 而不是 wsHttpBinding 还是二进制编码 定制绑定 这对我来说很好,因为压缩因子比二进制编码器的优势更大(它将消息大小减少了相当多,但不是压缩给出的10倍)。

        4
  •  0
  •   Mike H.    15 年前

    最好的办法是评估您遇到问题的特定mime类型(例如Fiddler),并确保该类型包含在applicationHost中。配置。如果正确安装和配置了压缩,则失败的请求跟踪将让您知道压缩不是以“无匹配内容类型”的配置执行的。

        5
  •  0
  •   Moog    14 年前

    mime类型最有可能是 Application/octet-stream

        6
  •  0
  •   Brian    10 年前

    只为那些可能展望未来的人。我们升级到Windows 2012 server和IIS 8。用于IIS 7的旧配置压缩模拟类型不适用于IIS 8。

    所以,我在这里尝试了一些建议,但没有任何效果。最后,我把这个添加到了httpcompression动态类型中: multipart/* 然后gzip压缩又开始工作了。

        7
  •  0
  •   e36M3    10 年前

    很多人都在努力为WCF服务启用IIS级别的压缩。主要是人们在wsHttpBinding上苦苦挣扎,如果IIS中启用了动态压缩,basicHttpBinding会立即进行压缩。我不打算讨论如何启用动态压缩,因为它在许多不同的帖子中都有介绍,只需搜索 “iis压缩应用程序/soap+xml” .如前所述,如果您正确配置了所有内容,您应该能够看到使用压缩的WCF响应 内容编码:gzip 在响应标题中。我建议使用Fiddler跟踪您的请求/响应。这是我(任何其他人)使用basicHttpBinding的经验。接下来的问题是,为什么它不能与wsHttpBinding一起工作?毫无疑问,你已经读到这是因为 内容类型 这两个绑定之间是不同的。basicHttpBinding的用途 内容类型:text/xml;字符集=utf-8 wsHttpBinding使用的 内容类型:应用程序/soap+xml;字符集=utf-8 。默认IIS应用程序主机将覆盖前者。dynamicTypes下的配置设置。后者并非如此。您可能读到需要添加这个额外的mimeType并重新启动IIS来修复这个问题。这对一些人有效,但对很多人无效。一些人宣称它与wsHttpBinding不兼容。问题就在这里。有可能 应用程序主机。配置文件:

    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文件夹中,尽管您从未真正浏览过该文件夹。希望这能帮你省去很多时间的悲伤。

        8
  •  0
  •   rfcdejong    7 年前

    如果有人在Azure中作为WebApp托管时偶然发现了这一点,您可以配置applicationHost。在“扩展”下使用azure门户,使用名为“IIS管理器”的扩展进行配置。更多关于扩展本身的信息 https://github.com/shibayan/IISManager