WCF流式响应在大数据上失败

时间:2010-07-13 03:04:58

标签: c# wcf iis-7

我目前遇到的问题是使用WCF流在通过IIS托管时通过互联网返回大量序列化对象。我不确定这是网络问题还是WCF问题,但我认为这些症状很难证明是网络问题,正如我将在下面描述的那样。

对象是通过一个流发送的各种不同对象,其中大多数是小的,但是其中还有jpeg,每个对象的范围从10k-> 500k。我无法真正调和的不同案例是:

  1. 如果我们通过内部网络运行它,即使我们将传输的数据增加了10倍,因此我们也会发送数十亿字节的数据。
  2. 如果我们在托管解决方案的服务器上运行它,我们会在几分钟和几百兆字节的转移后收到错误(详见下文)。
  3. 如果我们在服务器上运行它但删除照片(仅发送其他数据)它会成功并在比失败更长的时间内发送大约40mb(更长的时间是因为处理其他数据需要更长的时间,所以这是预期的。)
  4. 我们测试过只是从网络服务器上下载一个1GB的文件(明显超过我们在本地网络上尝试过的任何测试)并且它成功多次没有问题。
  5. 我们收到客户端的错误是(注意:我们没有接近我们设置的3小时超时):

    System.Reflection.TargetInvocationException: An exception occurred during the operation, making the result invalid. Check InnerException for exception details. ---> 
    System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '03:00:00'. ---> 
    System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> 
    System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
    

    我们看到服务器端:

    System.ServiceModel.CommunicationException,
    System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 The remote host closed the connection. The error code is 0x80070016.
    

    WCF绑定设置是(稍微匿名化):

      <system.serviceModel>
        <serviceHostingEnvironment>
          <baseAddressPrefixFilters>
            <add prefix="http://anonymous"/>
          </baseAddressPrefixFilters>
        </serviceHostingEnvironment>
        <bindings>
          <basicHttpBinding>
            <binding name="StreamedHttpBindingConfig" transferMode="StreamedResponse" maxReceivedMessageSize="2147483647" maxBufferSize="8388608" sendTimeout="01:00:00">
              <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"
                maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" maxDepth="2147483647" />
              <security mode="None" />
            </binding>
          </basicHttpBinding>
        </bindings>
        <services>
          <service behaviorConfiguration="wsHttpBindingBehaviour" name="AnonymousName">
            <endpoint address="" binding="basicHttpBinding" bindingConfiguration="StreamedHttpBindingConfig" name="wsHttpBinaryBindingEndpoint" contract="Service.IAnonymous" />
            <endpoint address="mex" binding="mexHttpBinding" name="mexHttpBindingEndpoint" contract="IMetadataExchange" />
            <host>
              <baseAddresses>
                <add baseAddress="http://anonymous/Service" />
              </baseAddresses>
            </host>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior name="wsHttpBindingBehaviour">
              <serviceThrottling maxConcurrentCalls="160" maxConcurrentSessions="100" maxConcurrentInstances="100" />
              <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    

    服务合同是(方法/参数名称更改为匿名,但键入相同):

    System.ServiceModel.Channels.Message GetData(System.ServiceModel.Channels.Message request);
    

    对我来说这看起来像是一个网络问题,但是我无法想象为什么它会在较长的时间段内成功,如果是间歇性的网络问题,我会看不出为什么要下载大文件呢?如果是这样的话,我一直没有受到影响。有没有人知道这个的潜在原因,或者知道诊断它的下一步是什么?

2 个答案:

答案 0 :(得分:0)

CommunicationException是通用的,不会泄露底层异常。在将来,当报告错误时,我建议在服务器上启用IncludeExceptionDetailInFaults(来自ServiceBehaviorAttribute或来自配置行为),以便将异常信息发送回客户端,然后报告您详细了解的嵌套异常

例如:

<behaviors> 
            <serviceBehaviors> 
                <behavior 
                    <serviceMetadata httpGetEnabled="true" /> 
                    <serviceDebug includeExceptionDetailInFaults="true" /> 
                </behavior> 
            </serviceBehaviors> 
        </behaviors> 

根本不知道出了什么问题。以下是我建议的更多内容,我在另一篇文章中也提到过:

通常,一旦你这样做,你应该有更多关于服务方面什么是时髦的信息,并且可以很快地诊断问题。试试吧,请报告回来! :)

答案 1 :(得分:0)

我在很长一段时间内都在寻找解决方案,并添加了我发现的每个配置以增加数据量。最终帮助我的是<behavior> web.config标记下的这一行,在服务器端:

<dataContractSerializer maxItemsInObjectGraph ="2147483647"/>

并确保我在客户端具有相同的行为。