WCF 超时太早'Connection was closed unexpectedly'异常



当调用返回字符串"success"的方法时,WCF客户端在120秒后返回上述异常。来自服务器的日志显示它完全执行并在大约3分钟内完成。启用跟踪后,我看到没有抛出错误。任何帮助都将非常感激,因为来自类似问题的其他建议不幸没有帮助。谢谢!

编辑-解决:结果是客户端使用了Smoothwall过滤设备,该设备在两分钟后关闭连接。

异常:

System.ServiceModel.CommunicationException The underlying connection was closed: The connection was closed unexpectedly.
Stack Trace:    at System.Net.HttpWebRequest.GetResponse()
   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

InnerException:

System.Net.WebException The underlying connection was closed: The connection was closed unexpectedly.The underlying connection was closed: The connection was closed unexpectedly.
Stack Trace:    at System.Net.HttpWebRequest.GetResponse()
   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

据我所知,绑定设置正确,超时超过120秒。下面是客户端绑定:

<bindings>
  <customBinding>
      <binding name="CustomBinding_IPHG" closeTimeout="00:05:00"
          openTimeout="00:05:00" receiveTimeout="00:15:00" sendTimeout="00:15:00">
          <security authenticationMode="SecureConversation" requireDerivedKeys="false">
              <localClientSettings maxClockSkew="00:30:00" />
              <localServiceSettings maxClockSkew="00:30:00" />
              <secureConversationBootstrap authenticationMode="UserNameOverTransport">
                  <localClientSettings maxClockSkew="00:30:00" />
                  <localServiceSettings maxClockSkew="00:30:00" />
              </secureConversationBootstrap>
          </security>
          <textMessageEncoding>
              <readerQuotas maxStringContentLength="5242880" />
          </textMessageEncoding>
          <httpsTransport maxReceivedMessageSize="6553600" useDefaultWebProxy="true" />
      </binding>
  </customBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="commonBehaviour">
  <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
  <clientCredentials>
    <serviceCertificate>
      <authentication certificateValidationMode="PeerOrChainTrust"/>
    </serviceCertificate>
  </clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>

服务器绑定:

<bindings>
  <customBinding>
    <binding name="CommonBinding" closeTimeout="00:05:00" openTimeout="00:05:00" receiveTimeout="00:15:00" sendTimeout="00:15:00">
      <transactionFlow />
      <security authenticationMode="SecureConversation" requireDerivedKeys="false">
        <secureConversationBootstrap authenticationMode="UserNameOverTransport">
          <localServiceSettings maxClockSkew="00:30:00" />
          <localClientSettings maxClockSkew="00:30:00" />
        </secureConversationBootstrap>
        <localServiceSettings maxClockSkew="00:30:00" />
        <localClientSettings maxClockSkew="00:30:00" />
      </security>
      <textMessageEncoding>
        <readerQuotas maxStringContentLength="41943040"/>
      </textMessageEncoding>
      <httpsTransport maxBufferSize="41943040" maxReceivedMessageSize="41943040" />
    </binding>
  </customBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="BehaviorRBS">
      <serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
      <serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="false" />
      <dataContractSerializer maxItemsInObjectGraph="2147483647" />
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="PHGAPI.PHGUserNamePassValidator, PHGAPI"/>
        <serviceCertificate
                findValue="*.domainname.com"
                x509FindType="FindBySubjectName"
                storeLocation="LocalMachine"
                storeName="My" />
      </serviceCredentials>
      <serviceThrottling maxConcurrentCalls="200" maxConcurrentSessions="400" maxConcurrentInstances="600" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<services>
    <service behaviorConfiguration="BehaviorRBS" name="PHGAPI.iAPI">
      <endpoint address="" binding="customBinding" bindingConfiguration="CommonBinding" contract="PHGAPI.IiAPI" />
    </service>
</services>

这是所讨论方法的接口:

[OperationContract]
string SetSuspensions(List<Suspension> suspensions);

我会查看默认值为120秒的WCF和相关配置设置。为此,您可能需要查看HTTP.sys connectionTimeout值。

来自Microsoft文档:
由于以下原因,可以将连接视为非活动连接:

  • HTTP。sys Timer_ConnectionIdle定时器过期。连接
  • HTTP。sys Timer_EntityBody定时器过期。连接已过期在请求实体体到达之前。当很明显a请求有实体体,HTTP API打开Timer_EntityBody计时器。初始设置该定时器的限制为connectionTimeout值。每次都有另一个数据指示收到此请求后,HTTP API将重置计时器以给出在connectionTimeout中指定的连接时间属性。
  • HTTP。sys Timer_AppPool定时器过期。连接已过期请求在应用程序池队列中等待的时间过长服务器应用程序退出队列并处理它。这个超时时间connectionTimeout。

默认值为00:02:00(2分钟)。

http://www.iis.net/configreference/system.applicationhost/sites/sitedefaults/limits

好运。

跟踪这些问题可能会很痛苦。请尝试以下操作来帮助查找问题。

1)确定问题在哪里,即客户端或服务器。在IDE中以调试模式启动服务,然后使用WCF测试客户端而不是您自己的客户端来排除客户端配置问题。

2)安装并使用Fiddler2来检查从服务发送到的HTTP消息。您将看到是否从服务返回响应以及响应中包含的内容。

3)假设这是一个同步调用,让线程打开三分钟无论如何对性能都是不利的。也许可以考虑重构服务,以便更快地返回数据或使其异步。

根据你的问题和下面的评论中发布的信息,在我看来,这是这个方程的客户端部分的超时。因为生成的客户机上的默认超时非常小。只需让您的客户端修改其配置以增加超时时间。

——put (client config)——

<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IService1" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"  />
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1/"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1"
                contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" />
        </client>
    </system.serviceModel>
</configuration>
你使用的绑定是不同的,但是所有的绑定都有这些属性。我通常会增加所有的超时,但对你来说最重要的是"receiveTimeout"

客户端位于何处?(同一公司网络,同一国家)

客户端的网络速度是多少?

参数List挂起的字节数是多少?

您是否尝试使用Fiddler或其他网络软件包软件来捕获传输?

在之前的作业中,有一种情况,服务器中的每个错误都被记录到不同的服务器;问题是,有10,000行错误的传入消息被发送到日志,但不是作为单个失败错误发送,而是作为相同错误的10,000倍发送。

序列化这个巨大的200MB以上的对象发送到另一个服务器会导致内部网络被视为100%被利用,并且使服务器达到100%,因此IIS无法及时响应任何其他请求。

我不是说这可能是你的情况,我只是分享一个超时的情况,我有问题不是在方法超时,而是在服务中的另一个组件。

建议您在业务逻辑方法中使用事务作用域。

如果您遇到这种错误,请停止数据库服务器并重新启动。我想这也许能解决你的问题。因为有时数据库流量阻塞花费的时间比开发人员预期的要长。因此,如果您的应用程序很重,那么就减少从应用程序到服务器的数据库调用。

相关内容

最新更新