【问题标题】:CommunicationException when Converting WCF Service from WsHttpBinding to NetTcpBinding将 WCF 服务从 WsHttpBinding 转换为 NetTcpBinding 时发生 CommunicationException
【发布时间】:2012-12-06 19:17:04
【问题描述】:

我有一个自托管的 .Net 4.0 WCF 服务,出于性能原因,我正在尝试将其从 WsHttpBinding 转换为 NetTcpBinding。该服务与 WsHttpBinding 一起工作得很好。

奇怪的是,该服务在切换到 NetTcpBinding 后似乎可以工作。 (服务将消息发布到企业消息系统,并且消息被发布并且客户端没有收到错误)但是以下错误被写入服务器日志:

Error: Service: MessageSenderService, Details: System.ServiceModel.CommunicationException: 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 '10675199.02:48:05.4775807'. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   at System.ServiceModel.Channels.SocketConnection.HandleReceiveAsyncCompleted()
   at System.ServiceModel.Channels.SocketConnection.BeginReadCore(Int32 offset,Int32 size, TimeSpan timeout, WaitCallback callback, Object state)
   --- End of inner exception stack trace ---
   at System.ServiceModel.Channels.SocketConnection.BeginReadCore(Int32 offset,Int32 size, TimeSpan timeout, WaitCallback callback, Object state)
   at System.ServiceModel.Channels.TracingConnection.BeginRead(Int32 offset, Int32 size, TimeSpan timeout, WaitCallback callback, Object state)
   at System.ServiceModel.Channels.SessionConnectionReader.BeginReceive(TimeSpan timeout, WaitCallback callback, Object state)
   at System.ServiceModel.Channels.SynchronizedMessageSource.ReceiveAsyncResult.PerformOperation(TimeSpan timeout)
   at System.ServiceModel.Channels.SynchronizedMessageSource.SynchronizedAsyncResult`1..ctor(SynchronizedMessageSource syncSource, TimeSpan timeout, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.TransportDuplexSessionChannel.BeginReceive(TimeSpan timeout, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.TransportDuplexSessionChannel.TryReceiveAsyncResult..ctor(TransportDuplexSessionChannel channel, TimeSpan timeout, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.TransportDuplexSessionChannel.BeginTryReceive(TimeSpan timeout, AsyncCallback callback, Object state)
   at System.ServiceModel.Dispatcher.ErrorHandlingReceiver.BeginTryReceive(TimeSpan timeout, AsyncCallback callback, Object state)

同样,使用 WsHttpBinding 时服务器日志上不会出现错误。

服务器配置:

      <service behaviorConfiguration="debugEnabled" name="My.Service">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="netTcpBindingConfig"
          contract="My.Service.Contract" />
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
....
    <behaviors>
      <serviceBehaviors>
        <behavior name="debugEnabled">
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceThrottling maxConcurrentSessions="200" maxConcurrentCalls="500" maxConcurrentInstances="200"/>
          <serviceMetadata httpGetEnabled="true" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
....
    <bindings>
      <netTcpBinding>
        <binding name="netTcpBindingConfig" maxReceivedMessageSize="5242880" closeTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00" openTimeout="00:01:00">
          <readerQuotas maxArrayLength="5242880" />
          <security mode="None" />
        </binding>
      </netTcpBinding>
    </bindings>

我们在代码中构建客户端绑定,而不是配置。看起来像这样:

return new NetTcpBinding(SecurityMode.None, reliableSessionEnabled)
{
    MaxBufferPoolSize = Int32.MaxValue,
    MaxReceivedMessageSize = Int32.MaxValue,
    ReaderQuotas = new XmlDictionaryReaderQuotas
    {
        MaxArrayLength = Int32.MaxValue,
        MaxDepth = Int32.MaxValue,
        MaxStringContentLength = Int32.MaxValue
    },
    ReceiveTimeout = TimeSpan.FromMinutes(1.0),
    CloseTimeout = TimeSpan.FromMinutes(1.0),
    OpenTimeout = TimeSpan.FromMinutes(1.0),
    SendTimeout = TimeSpan.FromMinutes(1.0)
};

有什么想法吗?

编辑:我想补充一点,我在每次调用服务时都会看到错误,而不仅仅是在负载下。请求和响应消息非常小,因此可能与消息大小无关。错误几乎是瞬间写入的,所以它不是超时问题。

【问题讨论】:

  • ReceiveTimeout 1 分钟太短,因此您的连接将在 1 分钟激活后终止
  • 错误立即发生,我绝对没有达到 1 分钟超时。
  • 所以使用switchValue="All" 启用 WCF 跟踪日志,您可能会发现更多详细信息
  • +1 在跟踪中。 Here is detailed setup 用于启用服务跟踪
  • 我在客户端和服务器上都启用了跟踪。我可以看到异常被抛出,但没有什么是根本原因。不知道如何在此站点上共享跟踪。

标签: wcf nettcpbinding


【解决方案1】:

修复它。

事实证明,我没有正确关闭客户端代理。无论出于何种原因,不会导致 WsHttpBinding 出现问题,但使用 NetTcpBinding 会导致该错误。

将客户端代理放入 using 块后,问题就消失了。

【讨论】:

  • 这是众所周知的错误 - 通过 suign 块包装代理,只需在 stackoverflow 中搜索如何正确关闭 WCF 代理
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
  • 2010-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多