WCF超时太快& '连接意外关闭'例外

时间:2014-03-19 13:41:59

标签: c# .net wcf exception iis

当调用返回字符串" 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);

5 个答案:

答案 0 :(得分:4)

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

从Microsoft文档:
由于以下原因,连接可被视为非活动状态:

  • HTTP.sys Timer_ConnectionIdle计时器已过期。连接 已过期且仍然无所事事。
  • HTTP.sys Timer_EntityBody计时器已过期。连接已过期 在请求实体主体到达之前。当它显然是一个 请求有一个实体主体,HTTP API打开 Timer_EntityBody计时器。最初,此计时器的限制设置为 connectionTimeout值。每次另一个数据指示 收到此请求后,HTTP API重置计时器以提供 连接更多分钟,如connectionTimeout中指定的那样 属性。
  • HTTP.sys Timer_AppPool计时器已过期。连接已过期 因为请求在应用程序池队列中等待的时间太长 服务器应用程序出列并处理它。这个超时持续时间 是connectionTimeout。

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

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

祝你好运。

答案 1 :(得分:2)

追踪这些问题可能很痛苦。请尝试以下方法来帮助解决问题。

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

2)安装并使用Fiddler2来检查来自服务的HTTP消息。您将看到是否有来自该服务的响应以及其中包含的内容。

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

答案 2 :(得分:2)

根据您的问题中发布的信息和下面的评论,听起来像是这个等式的客户端部分超时。由于生成的客户端上的默认超时非常小。只需让您的客户修改其配置即可延长超时时间。

- 施加(客户端配置) -

<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”

答案 3 :(得分:2)

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

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

参数列表暂停的大小(以字节为单位)是多少?

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

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

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

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

答案 4 :(得分:-3)

建议您在业务逻辑方法中使用事务范围。

如果您遇到此类错误,请停止数据库服务器并重新启动。我想这可能会解决你的问题。因为有时数据库流量拥塞需要的时间比开发人员预期的要长。因此,如果您的应用程序繁重,请从应用程序到服务器进行较少的数据库调用。