我有一个自托管的 .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)
};
有什么想法吗?
编辑:我想补充一点,我在每次调用服务时都会看到错误,而不仅仅是在负载下。请求和响应消息非常小,因此可能与消息大小无关。该错误几乎是立即写入的,因此它不是超时问题。