WCF 服务 Net TCP 套接字连接在 15 分钟后总是中止,无论绑定配置如何
WCF service Net TCP socket connection get aborted after 15 minutes, always and regardless of binding configuration
我有一个 WCF 服务(不是通过 IIS 托管的)并且我有另一个应用程序通过网络 TCP 与我的 WCF 通信。除了长 运行 操作外,一切都很好。我的 WCF 可能会执行 运行 查询或备份数据库等任务。这些任务可能需要几分钟或几小时才能完成。异步执行这些任务也不是一个选项。
问题:在 15 分钟标记处,套接字连接中止,我似乎无法弄清楚这是从哪里来的...
这里是 WCF 服务的配置:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBindingConfigurationForMyWCF"
openTimeout="24:00:00"
closeTimeout="24:00:00"
sendTimeout="24:00:00"
receiveTimeout="24:00:00"
maxReceivedMessageSize="9223372036854775807"
transferMode="Streamed">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" />
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="Namespace.MyWCF">
<endpoint address=""
binding="netTcpBinding"
bindingConfiguration="NetTcpBindingConfigurationForMyWCF"
name="NetTcpBindingEndpointMyWCF"
contract="MyWCF.IMyWCF" />
<endpoint address="mex"
binding="mexTcpBinding"
bindingConfiguration=""
name="MexTcpBindingEndpoint"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://SQLServer/MyWCF" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000"/>
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
这是我的应用程序的配置:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBindingConfigurationForMyWCF"
openTimeout="24:00:00"
closeTimeout="24:00:00"
sendTimeout="24:00:00"
receiveTimeout="24:00:00"
maxReceivedMessageSize="9223372036854775807"
transferMode="Streamed">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" />
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://SQLServer/MyWCF"
binding="netTcpBinding"
bindingConfiguration="NetTcpBindingConfigurationForMyWCF"
contract="MyWCF.IMyWCF"
name="NetTcpBindingEndpointMyWCF">
</endpoint>
</client>
这是我到目前为止拼命尝试的方法,没有任何运气:
- 将所有超时值设置为 24 小时
- 为 serviceThrottling 添加了 maxConcurrentCalls、maxConcurrentInstances 和 maxConcurrentSessions
值较大的配置
- 在两台服务器上禁用防火墙
-启用nettcp绑定端口共享
- 启用了 inactivityTimeout = 24h
的可靠会话
无论我如何尝试,15 分钟后我都会收到以下错误:
Exception msg: An existing connection was forcibly closed by the remote host
Exception type: System.Net.Sockets.SocketException
Stack trace: at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
Exception msg: 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 '23.23:59:59.9843758'.
Exception type: System.ServiceModel.CommunicationException
Stack trace: at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
at System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
at System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
at System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.Security.NegotiateStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
我最终找到了这个超时的根本原因,如果其他人遇到同样的问题,我会回答我自己的问题。
我们服务器之间的所有通信都经过防火墙。我们使用具有 TCP 不活动超时配置的 SonicWall...默认值为 15 分钟,这是我超时的来源。
我最终实现了一种基于长 运行 操作句柄的机制。我的调用应用程序将请求一个操作并在 return 中接收一个句柄。然后应用程序可以使用句柄通过定期调用 WCF 来获取操作状态的更新,直到操作完成。
问题已解决!
我有一个 WCF 服务(不是通过 IIS 托管的)并且我有另一个应用程序通过网络 TCP 与我的 WCF 通信。除了长 运行 操作外,一切都很好。我的 WCF 可能会执行 运行 查询或备份数据库等任务。这些任务可能需要几分钟或几小时才能完成。异步执行这些任务也不是一个选项。
问题:在 15 分钟标记处,套接字连接中止,我似乎无法弄清楚这是从哪里来的...
这里是 WCF 服务的配置:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBindingConfigurationForMyWCF"
openTimeout="24:00:00"
closeTimeout="24:00:00"
sendTimeout="24:00:00"
receiveTimeout="24:00:00"
maxReceivedMessageSize="9223372036854775807"
transferMode="Streamed">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" />
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="Namespace.MyWCF">
<endpoint address=""
binding="netTcpBinding"
bindingConfiguration="NetTcpBindingConfigurationForMyWCF"
name="NetTcpBindingEndpointMyWCF"
contract="MyWCF.IMyWCF" />
<endpoint address="mex"
binding="mexTcpBinding"
bindingConfiguration=""
name="MexTcpBindingEndpoint"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://SQLServer/MyWCF" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000"/>
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
这是我的应用程序的配置:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBindingConfigurationForMyWCF"
openTimeout="24:00:00"
closeTimeout="24:00:00"
sendTimeout="24:00:00"
receiveTimeout="24:00:00"
maxReceivedMessageSize="9223372036854775807"
transferMode="Streamed">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" />
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://SQLServer/MyWCF"
binding="netTcpBinding"
bindingConfiguration="NetTcpBindingConfigurationForMyWCF"
contract="MyWCF.IMyWCF"
name="NetTcpBindingEndpointMyWCF">
</endpoint>
</client>
这是我到目前为止拼命尝试的方法,没有任何运气:
- 将所有超时值设置为 24 小时
- 为 serviceThrottling 添加了 maxConcurrentCalls、maxConcurrentInstances 和 maxConcurrentSessions
值较大的配置
- 在两台服务器上禁用防火墙
-启用nettcp绑定端口共享
- 启用了 inactivityTimeout = 24h
无论我如何尝试,15 分钟后我都会收到以下错误:
Exception msg: An existing connection was forcibly closed by the remote host
Exception type: System.Net.Sockets.SocketException
Stack trace: at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
Exception msg: 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 '23.23:59:59.9843758'.
Exception type: System.ServiceModel.CommunicationException
Stack trace: at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
at System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
at System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
at System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.Security.NegotiateStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
我最终找到了这个超时的根本原因,如果其他人遇到同样的问题,我会回答我自己的问题。
我们服务器之间的所有通信都经过防火墙。我们使用具有 TCP 不活动超时配置的 SonicWall...默认值为 15 分钟,这是我超时的来源。
我最终实现了一种基于长 运行 操作句柄的机制。我的调用应用程序将请求一个操作并在 return 中接收一个句柄。然后应用程序可以使用句柄通过定期调用 WCF 来获取操作状态的更新,直到操作完成。
问题已解决!