System.ServiceModel.CommunicationException:底层连接已关闭

Posted

技术标签:

【中文标题】System.ServiceModel.CommunicationException:底层连接已关闭【英文标题】:System.ServiceModel.CommunicationException: The underlying connection was closed 【发布时间】:2013-10-31 09:19:56 【问题描述】:

我正在从 wcf Web 服务检索数据,当数据超过 20 万条记录时,我得到一个异常,如下所示:

System.ServiceModel.CommunicationException: The underlying connection was closed: A connection that was expected to be kept alive was closed by the server. ---> System.Net.WebException: The underlying connection was closed: A connection that was expected to be kept alive was closed by the server. ---> 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
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
--- End of inner exception stack trace ---

Server stack trace: 
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

我的 web.config 如下所示:

<basicHttpBinding>
  <binding name="BasicHttpBinding_IService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
             maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
             allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
             messageEncoding="Text" textEncoding="utf-8" transferMode="StreamedResponse" useDefaultWebProxy="true">
    <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"
                  maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
    <security mode="None">
      <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
      <message clientCredentialType="UserName" algorithmSuite="Default" />
    </security>
  </binding>
  <binding maxReceivedMessageSize="2147483647" allowCookies="true">
    <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
  </binding>
</basicHttpBinding>

我确信我的网络服务正在从数据库中检索数据。但无法从我发起呼叫的位置转移到我的网站。提前感谢您的帮助。

【问题讨论】:

在配置文件中增加连接超时时间。 在Web.config中提到的绑定中增加maxBufferSize,maxReceivedMessageSize 【参考方案1】:

我最近在 .Net 4.0 Web 应用程序中的 Wcf 服务遇到了同样的问题。我增加了 maxItemsInObjectGraph 值,服务器不再抛出异常。文档here 说默认最大值是 Int32.MaxValue 但我认为它不正确,最大值是 65535。

   <serviceBehaviors>
    <behavior name="ServiceBehaviour">
      <dataContractSerializer maxItemsInObjectGraph="6553500"/>
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>

您可以做的另一件事是启用跟踪。这是我在 web.config 中的一个示例:

<system.diagnostics>
  <sources>
    <source name="System.ServiceModel"
            switchValue="Information, ActivityTracing"
            propagateActivity="true">
      <listeners>
        <add name="traceListener"
            type="System.Diagnostics.XmlWriterTraceListener"
            initializeData= "c:\temp\log\Traces.svclog" />
      </listeners>
    </source>
  </sources>
</system.diagnostics>

如果您双击 Traces.svclog,窗口应该会打开 Microsoft Service Trace Viewer。

如果您使用 Microsoft WCF 测试客户端测试您的服务,请确保更改默认客户端配置以匹配服务器设置(这包括客户端端点行为),以确保客户端可以接收来自服务器的响应。

我希望这会有所帮助。

【讨论】:

我遇到了和 OP 类似的问题,添加 &lt;dataContractSerializer maxItemsInObjectGraph="..." /&gt; 为我解决了这个问题。 我也有类似的问题。使用服务跟踪日志,我发现我的 DTO 类的序列化错误... 链接中的文档指向 System.Runtime.Serialization 类。这是服务行为的链接,显示最大值为 65536 msdn.microsoft.com/en-us/library/ms731809(v=vs.100).aspx +1 用于提醒有关跟踪的信息 - 一直忘记该功能。他们真的应该将“实际”错误文本传播到正在抛出的 CommunicationException 中......【参考方案2】:

使您的客户端 basicHttpBinding 与您的服务器绑定相同。这是一个非常常见的错误,只更改一个绑定而不是服务器和客户端绑定。

如果这不起作用,您可以启用 wcf 跟踪: wcf tracing

这将使您更深入地了解潜在问题是什么。

【讨论】:

【参考方案3】:

我们的对象图中有一个循环正在返回。我知道这可能不是你的问题,但我在这里添加它以防其他人有同样的问题。我们启用了 includeExceptionDetailInFaults,但在任何客户端(我们的应用程序或 WCF 测试客户端)中都没有收到错误。幸运的是,它出现在服务器日志中,所以我们能够以这种方式找到它。

我们有 Parent -> child 和 child -> parent 进行双向导航,我们不得不断开该链接,而是让 parent -> child,并且孩子有一个 id 来查找 parent,然后错误就消失了.

希望这对某人有所帮助!

【讨论】:

【参考方案4】:

将以下配置添加到您的 wcf 服务配置中。并查看 c:\log\Traces.svclog 文件。 我的异常是 throw for ;

尝试序列化参数时出错 InnerException 消息是“枚举值 '0”对于类型“ThyCams2014.XrmBase.new_filingstatu”无效并且无法序列化。如果类型具有 DataContractAttribute 属性代码 herebute,请确保存在必要的枚举值并使用 EnumMemberAttribute 属性进行标记。有关详细信息,请参阅 InnerException。

<configuration>
   <system.diagnostics>
      <sources>
            <source name="System.ServiceModel" 
                    switchValue="Information, ActivityTracing"
                    propagateActivity="true">
            <listeners>
               <add name="traceListener" 
                   type="System.Diagnostics.XmlWriterTraceListener" 
                   initializeData= "c:\log\Traces.svclog" />
            </listeners>
         </source>
      </sources>
   </system.diagnostics>
</configuration>

【讨论】:

【参考方案5】:

这句话解决了我的问题:

db.ContextConfiguration.ProxyCreationEnabled = false;

【讨论】:

以上是关于System.ServiceModel.CommunicationException:底层连接已关闭的主要内容,如果未能解决你的问题,请参考以下文章