2011-05-11 63 views
11

我有超时问题,这些都是细节:WCF不正确计时?

我绑定配置是这样的:

<netTcpBinding> 
<binding name="WindowsServerOverTcp" 
    maxReceivedMessageSize="10000000" 
    maxBufferSize="10000000" 
    maxBufferPoolSize="10000000" 
    closeTimeout="00:00:03" 
    openTimeout="00:00:03" 
    sendTimeout="00:00:03" 
    receiveTimeout="00:00:03"> 
    <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" 
    maxArrayLength="2147483647" maxBytesPerRead="2147483647" 
    maxNameTableCharCount="2147483647" /> 
    <security mode="None"> 
    </security> 
</binding> 
</netTcpBinding> 

我发送消息给我知道被关闭,以便连接应的服务器按照我的app.config中规定的3秒后超时,但由于某种原因需要20-30秒。

当EndPointNotFoundException被抛出这样的信息,我得到:

System.ServiceModel.EndPointNotFoundException: 无法连接到 的net.tcp://10.0.0.82:4466/MegaMatcherWcf。 连接尝试持续时间为00:00:03,时间间隔为 。 TCP错误代码 10060:连接尝试失败 因为连接的方做了一段时间 后不 正确响应,或建立的连接失败 ,因为连接的主机没有 响应10.0.0.82:4466

如果我在打开机器的情况下尝试进行相同的测试,但没有运行监听软件,我会得到预期的行为,并在3秒后连接超时。为什么如果机器关机,需要30秒钟,然后告诉我需要3秒钟?

回答

9

我相信你现在正在处理Windows超时问题,而不是你的WCF超时。 Windows需要20-30秒才能确定机器没有在网络上响应。当你打电话给WCF服务器时,Windows首先必须建立到服务器的路由。当它不能时,它会提醒你的软件,你的软件认为它达到了它自己的超时时间。您的系统永远不会到达实际轮询的位置,以查看服务是否正在运行,因为Windows仍在尝试在该IP地址的另一端找到某些东西。

+0

只是为了澄清,我让每个连接都是一个新的连接,我没有抱着到现有的连接。我会考虑考虑这是一种微软技术,他们将覆盖默认的TCP超时时间这种情况下?如果只有打开机器才能使用connectTimeout属性,那么它有什么意义? – Adrian 2011-05-11 15:22:31

+0

@Adrian - 这是令人沮丧的,但我相信这是这种情况的原因是因为WCF让操作系统建立基础连接(获取服务器的路径)。这是让操作系统做到最好。不幸的是,这意味着当服务器关闭时,我们依赖于操作系统超时。 – IAmTimCorey 2011-05-11 15:28:41

+0

@ BiggsTRC感谢您的信息,真的让我感到困惑,我会记得下一次!我将不得不将所有连接都连接到SmartThread池,以便这些超时不会减慢我的应用程序。 – Adrian 2011-05-11 15:52:08

15

为比@BiggsTRC(其答案是正确的广义)更具体一点:

  • WCF委托给System.Net.Sockets类 建立在一个 通道NetTcpBinding的传输层连接的细节;
  • System.Net.Sockets是非托管WINSOCK API的包装;
  • WINSOCK API具有内部默认超时,但不提供任何记录的机制来指定某些阻止操作的超时,包括WSAConnect(),.NET Socket.Connect()方法使用;
  • WCF代码(在System.ServiceModel.Channels.SocketConnectionInitiator.Connect()中)调用Socket.Connect,并且如果这引发了某些类型的异常,它会检查连接超时期限是否有任何剩余时间。如果没有,你会得到一个EndpointNotFoundException以及你所看到的错误信息;
  • WCF使用TimeoutHelper类来跟踪超时周期并进行时间算术运算。这有一个名为ElapsedTime的方法,但这是一个误称,因为它永远不会返回大于原始超时时间的值:这就是错误消息对您连接尝试花费多长时间的原因。

WCF可以通过使用Sockets API的异步方法强制其配置的超时,监视连接尝试的单独线程上的超时,但目前它不这样做。如果您认为这是一个错误(可以证明这是错误),您可以在Microsoft's Connect Site上报告它,并且可能会在未来的版本或服务包中修复它。

+1

感谢您输入Chris,我可能会报告这一点,因为提供一个超时参数并不是有效的连接超时。你会认为考虑MS开发的WCF,他们可以轻松地覆盖API的默认值。 – Adrian 2011-05-24 12:08:24

1

正面临着同样的问题

以下配置救了我的一天

现在没说时间,直到5分钟

服务器端

<system.serviceModel> 
<diagnostics> 
    <messageLogging logMalformedMessages="true" logMessagesAtTransportLevel="true" /> 
</diagnostics> 
<bindings> 
    <netTcpBinding> 
    <binding name="meritBasicBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" 
      closeTimeout="00:05:00" openTimeout="00:05:00" sendTimeout="00:05:00" receiveTimeout="00:05:00"> 
     <readerQuotas maxDepth="128" maxStringContentLength="8388608" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/> 
     <reliableSession ordered="true" inactivityTimeout="00:05:00" enabled="false"/> 
     <security mode="Transport"> 
     <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/> 
     </security> 
    </binding> 
    </netTcpBinding> 
</bindings> 
<services> 
    <service name="Merit.Services.Reporting" behaviorConfiguration="mexBehaviour"> 
    <endpoint address="Reporting" binding="netTcpBinding" behaviorConfiguration="meritEndPointBehaviour" bindingConfiguration="meritBasicBinding" contract="Merit.Services.IReporting"></endpoint>   
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"></endpoint> 
    <host> 
     <baseAddresses> 
     <add baseAddress="net.tcp://Localhost:8090/"/> 
     </baseAddresses> 
    </host> 
    </service> 
</services> 
<behaviors> 
    <serviceBehaviors> 
    <behavior name="mexBehaviour"> 
     <serviceMetadata httpGetEnabled="false"/> 
     <serviceDebug includeExceptionDetailInFaults="true"/> 
     <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
    </behavior> 
    </serviceBehaviors> 
    <endpointBehaviors> 
    <behavior name="meritEndPointBehaviour"> 
     <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
    </behavior> 
    </endpointBehaviors> 
</behaviors> 

客户端边

<system.serviceModel> 
<bindings> 
    <netTcpBinding> 
    <binding name="meritBasicBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" listenBacklog="2147483647" 
      closeTimeout="00:05:00" openTimeout="00:05:00" sendTimeout="00:05:00" receiveTimeout="00:05:00"> 
     <readerQuotas maxDepth="128" maxStringContentLength="8388608" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/> 
     <security mode="Transport"> 
     <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/> 
     </security> 
    </binding> 
    </netTcpBinding> 
</bindings> 
<client> 
    <endpoint address="net.tcp://Localhost:8090/Reporting" binding="netTcpBinding" 
    bindingConfiguration="meritBasicBinding" behaviorConfiguration="meritEndPointBehaviour" contract="MeritReportingService.IReporting" 
    name="NetTcpBinding_IReporting"> 
    <identity> 
     <servicePrincipalName value="host/SERVER DOMAIN ADDRESS(usually picked automatically)" /> 
    </identity> 
    </endpoint> 
</client> 
<behaviors> 
    <endpointBehaviors> 
    <behavior name="meritEndPointBehaviour"> 
     <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
    </behavior> 
    </endpointBehaviors> 
</behaviors>