【问题标题】:WCF service Net TCP socket connection get aborted after 15 minutes, always and regardless of binding configurationWCF 服务网络 TCP 套接字连接在 15 分钟后中止,无论绑定配置如何
【发布时间】:2020-03-16 21:07:00
【问题描述】:

我有一个 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 小时
- 为 maxConcurrentCalls、maxConcurrentInstances 和 maxConcurrentSessions 添加了较大值的 serviceThrottling 配置
- 禁用两台服务器上的防火墙
- 启用 nettcpbinding 端口共享
- 启用 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)

【问题讨论】:

  • 我认为处理这些耗时任务的最佳方法是异步执行或设置为 One-Way。然后我们将处理结果记录在数据库中或设置在字典中,key为TaskID,Value为处理结果。此外,消息队列可能是另一种选择。
  • @Abraham 是的,这将是我的下一步。考虑返回一个句柄,允许调用函数定期检查操作状态

标签: sockets wcf service connection net-tcp


【解决方案1】:

我最终找到了这个超时的根本原因,并会回答我自己的问题,以防其他人遇到同样的问题。

我们服务器之间的所有通信都要经过防火墙。我们使用具有 TCP 不活动超时配置的 SonicWall...默认值是 15 分钟,这是我的超时时间。

我最终实现了一种基于句柄的机制,用于长时间运行的操作。我的调用应用程序将请求一个操作并接收一个句柄作为回报。然后应用程序可以使用句柄通过定期调用 WCF 来获取操作状态的更新,直到操作完成。

问题解决了!

【讨论】:

    猜你喜欢
    • 2012-03-28
    • 2019-07-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    • 2017-01-06
    • 2012-01-03
    • 2021-08-10
    • 1970-01-01
    相关资源
    最近更新 更多