1

I have a self hosted .Net 4.0 WCF service that I'm trying to convert from WsHttpBinding to NetTcpBinding for performance reasons. The service works just fine with the WsHttpBinding.

Strangely enough, The service seems to work after switching to NetTcpBinding. (The service posts messages to a enterprise messaging system, and the message is posted and the client receives no error) however the following error is written to the server log:

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)

Again, no error occurs on the server log when using the WsHttpBinding.

Server Config:

      <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>

We build the client binding in code, not config. That looks like this:

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)
};

Any ideas out there?

EDIT: I would like to add that I see the error on every call to the service, not only under load. The request and response messages are very small so it likely not related to message size. The error is written almost instantaneously, so it it not a timeout problem.

johnmcase
  • 1,769
  • 2
  • 16
  • 27
  • ReceiveTimeout 1 minute ofthen is too short, so your connection will be terminated after 1 minute being active – sll Dec 06 '12 at 19:27
  • The error happens immediately, I am definitely not hitting a 1 minute timeout. – johnmcase Dec 06 '12 at 19:36
  • So enable WCF Trace logs with `switchValue="All"` there you might find more details – sll Dec 06 '12 at 19:39
  • +1 On trace. [Here is detailed setup](http://stackoverflow.com/questions/10925697/debug-ef4-savechanges-in-wcf-service-hosted-by-iis) for enabling service trace – Petar Vučetin Dec 06 '12 at 19:51
  • I have enabled trace on both the client and server. I can see the exception being thrown, but nothing is jumping out at me as a root cause. Not sure how I can share the trace on this site. – johnmcase Dec 06 '12 at 19:55
  • Use http://pastebin.com/ – Petar Vučetin Dec 06 '12 at 20:45

1 Answers1

1

Fixed it.

As it turns out, I was not properly closing the client proxy. For whatever reason that didn't cause a problem with the WsHttpBinding, but with NetTcpBinding it caused that error.

After putting the client proxy in a using block the problem went away.

johnmcase
  • 1,769
  • 2
  • 16
  • 27
  • this is well known error - wrapping proxy by suign block, just do a search in stackoverflow about how properly close WCF proxy – sll Dec 07 '12 at 11:00