【问题标题】:WCF Service with large parameters具有大参数的 WCF 服务
【发布时间】:2011-06-16 18:10:05
【问题描述】:

我查看了许多关于 SO 的类似主题,但没有找到一个对此有帮助的主题。

拥有一个接收 XML 进行处理的 WCF 服务。我正在读取的 XML 文件约为 600K。

该调用适用于小型 xml 文件(大部分时间),但在较大的文件上我收到错误:

System.ServiceModel.Security.MessageSecurityException:
从另一方收到不安全或不正确安全的故障。故障代码和细节见内部FaultException。

内部异常在哪里:

System.ServiceModel.FaultException:
无法处理该消息。这很可能是因为操作“http://tempuri.org/ISapListener/ProcessSapRoles”不正确,或者因为消息包含无效或过期的安全上下文令牌,或者因为绑定之间存在不匹配。如果服务由于不活动而中止通道,则安全上下文令牌将无效。为防止服务过早中止空闲会话,请增加服务端点绑定的接收超时。

就像我说的...它适用于小文件,我的打开、发送、接收、关闭和不活动超时都设置为 10 分钟。它会在大约 20-30 秒内失败。

此外,服务器和客户端上的时钟完全同步(我已经看到作为答案发布)。

我目前的配置文件(我玩过很多设置):

服务器:

<bindings>
  <wsHttpBinding>
    <binding name="wsHttpBinding_Custom" closeTimeout="00:00:10"
             openTimeout="00:01:00" receiveTimeout="00:10:00"
             sendTimeout="00:10:00" bypassProxyOnLocal="false" 
             transactionFlow="false" hostNameComparisonMode="StrongWildcard"
             messageEncoding="Text" textEncoding="utf-8" 
             useDefaultWebProxy="true" allowCookies="false"
             maxReceivedMessageSize="1024768"            
             maxBufferPoolSize="1024768" >
      <readerQuotas maxDepth="32" maxBytesPerRead="4096" 
                    maxNameTableCharCount="16384" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00" 
                       enabled="false" />
      <security mode="Message">
        <transport clientCredentialType="Windows" proxyCredentialType="None" 
                   realm="" />
        <message clientCredentialType="Windows" 
                 negotiateServiceCredential="true"
                 algorithmSuite="Default" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>
<services>
  <service behaviorConfiguration="CSA.GS3.Services.SapListenerBehavior" 
           name="CSA.GS3.Services.SapListener">
    <endpoint address="" binding="wsHttpBinding"  
              bindingConfiguration="wsHttpBinding_Custom" 
              contract="CSA.GS3.Services.ISapListener">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" 
              contract="IMetadataExchange" />
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="CSA.GS3.Services.SapListenerBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>

客户:

<bindings>
  <wsHttpBinding>
    <binding name="WSHttpBinding_ISapListener1" 
             closeTimeout="00:10:00" openTimeout="00:10:00" 
             receiveTimeout="00:10:00" sendTimeout="00:10:00"
             bypassProxyOnLocal="false" transactionFlow="false"
             hostNameComparisonMode="StrongWildcard"
             messageEncoding="Text" textEncoding="utf-8" 
             useDefaultWebProxy="true" allowCookies="false"
             maxBufferPoolSize="1024768" 
             maxReceivedMessageSize="1024768">
      <readerQuotas maxDepth="32" maxBytesPerRead="4096" 
                    maxNameTableCharCount="16384" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00"
                       enabled="false" />
      <security mode="Message">
        <transport clientCredentialType="Windows" proxyCredentialType="None"
          realm="" />
        <message clientCredentialType="Windows" 
                 negotiateServiceCredential="true"
                 algorithmSuite="Default" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>
<client>
  <endpoint address="http://gs3-test.us.tycoelectronics.com/SapListener/SapListener.svc"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ISapListener1"
            contract="Gs3TestSapListener.ISapListener" 
            name="WSHttpBinding_ISapListener1">
    <identity>
      <dns value="localhost" />
    </identity>
  </endpoint>
</client>

我确实在服务上启用了跟踪,但我无法从日志文件中理解。

我在使用配置设置时收到的其他异常:

System.ServiceModel.Security.SecurityNegotiationException
无法打开安全通道,因为与远程端点的安全协商失败。

System.ServiceModel.ServiceActivationException
无法激活请求的服务“http://../SapListener.svc”。

【问题讨论】:

  • 大文件总是失败吗?
  • 是的...小的通常可以工作,虽然我有时会遇到一些问题,但通常要么重新启动服务或重试就可以解决它
  • 顺便问一下,有没有一种情况可以在本地工作,但不能针对远程客户端?那就是你有一个在本地运行并发送大内容的测试客户端并且它不会失败?
  • 对于哪些场景有效,哪些无效,这有点令人困惑。有一次我确信它在本地工作,但当我将它部署到服务器时,我不会发誓,虽然

标签: c# wcf wcf-client


【解决方案1】:

如果可能并且客户可以接受,您可以将文件分解成更小的块并发送出去,前提是您没有数字证书等和客户端的排序选项。

【讨论】:

    【解决方案2】:

    我能够让它与以下配置一起工作:

    服务器:

    <bindings>
      <wsHttpBinding>
        <binding name="wsHttpBinding_Custom"
                 closeTimeout="00:10:00"
                 openTimeout="00:10:00"
                 receiveTimeout="00:10:00"
                 sendTimeout="00:10:00"
                 maxReceivedMessageSize="2097152"
                 bypassProxyOnLocal="false" transactionFlow="false" 
                 hostNameComparisonMode="StrongWildcard"
                 maxBufferPoolSize="2097152" messageEncoding="Text"
                 textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
          <readerQuotas maxDepth="32" maxBytesPerRead="4096" 
                        maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
          <security mode="Message">
            <transport clientCredentialType="Windows" proxyCredentialType="None" 
                       realm="" />
            <message clientCredentialType="Windows" negotiateServiceCredential="true" 
                     algorithmSuite="Default" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    

    客户:

    <bindings>
      <wsHttpBinding>
        <binding name="WSHttpBinding_ISapListener1" closeTimeout="00:10:00"
                 openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
                 bypassProxyOnLocal="false" transactionFlow="false" 
                 hostNameComparisonMode="StrongWildcard"
                 maxBufferPoolSize="2097152" 
                 maxReceivedMessageSize="2097152"
                 messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                 allowCookies="false">
          <readerQuotas maxDepth="32" maxBytesPerRead="4096" 
                        maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
                           enabled="false" />
          <security mode="Message">
            <transport clientCredentialType="Windows" proxyCredentialType="None"
                       realm="" />
            <message clientCredentialType="Windows" negotiateServiceCredential="true"
                     algorithmSuite="Default" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    

    我能看到的唯一区别是我提高了 maxReceivedMessageSize 和 maxBufferPoolSize...也许我还缺少其他东西?如果这是问题所在,那么问题在于我的通话开销是在我发送的 600K xml 数据中增加了 400+K

    【讨论】:

    • 还要注意最大数组对象数和最大对象大小等。像这样的东西在 WCF 中没有很好的记录,有时很难诊断。
    • 感谢您的警告...我会调查这些
    【解决方案3】:
    System.ServiceModel.ServiceActivationException
    The requested service, 'http://../SapListener.svc' could not be activated.
    

    这可能是编译错误或无效配置。

    它是 WCF 4.0 吗?然后您可以删除您的自定义配置并使用自动绑定。我还建议您尝试使用 wsHttpBinding 以外的绑定,例如 basicHttpBinding。

    【讨论】:

    • 更可能是无效配置,因为不需要重新编译。不幸的是,使用 3.5
    【解决方案4】:

    如果您认为能够理解日志文件会有所帮助,请使用 svcTraceViewer。只需确保您确实正确设置了跟踪。我的博客上有一篇关于此的文章。 svcTraveViewer Debugging WCF Services

    关于大型有效负载,您可能需要查看这篇 MSDN 文章。 http://msdn.microsoft.com/en-us/library/ms733742.aspx

    特别是流数据。

    【讨论】:

    • 谢谢...我正在使用 svcTraceViewer : \ 没有明显的错误或警告,只有信息,我认为启动/停止。我想我只是不知道要找什么。我会仔细看看那些文章。
    • 我最初没有使用流式传输的原因是因为我需要所有数据来处理它......我正在对 xml 运行 linq 查询,这在所有 xml 之前都是没有意义的被读取
    • 在 WCF 端,一旦您收到文档,就可以像往常一样处理它。我没有使用 WCF 完成此操作,但我无法想象整个管道必须依赖流。流媒体在客户端和服务器端之间。一旦服务器“接收”到文档,所有其他处理都应该保持不变。
    • 当然,但据我了解,流式传输的好处是您无需等待数据传入即可开始处理。我想我可以这样做只是为了解决必须弄清楚缓冲区大小的问题。我看到的错误可能会在此过程中消失...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    相关资源
    最近更新 更多