tags:

views:

619

answers:

1

I created a self hosted WCF service with netTcpBinding. I am using a WinForm based client to connect to this service. I have observed that while the client is up and running, I always lose connection to the WCF service - faulted state!.

To resolve this, I created a thread to keep the connection alive. I let the client sit and, after about a week, found an error message in my logs : TCP connection error 10061 - client was refused connection. The keep alive thread cannot recreate the connection object - the logs still display "connection refused".

In my configuration file for the service host, I have a base address but no endpoint address. MSDN says that the when no endpoint address is given, the endpoint address becomes the base address when the Open method is called.

Do I still need to give an endpoint address to resolve the "TCP connection refused" issue?

Thanks in advance for any advice.

A: 

I think the main problem is that you're trying to always keep a connection "alive" to a WCF service. That is not the way to do it with WCF services.

In WCF, the recommended best practice is to use "per-call" activation, e.g. your client call the service, a new isolated instance of the service class is created for that request and handles it, and then it's disposed and the connection between client and server is basically gone again.

Now NetTcpBinding is special in that it has a transport-level session with the server. However, you still should

  • create the client side proxy
  • call the service
  • close the client side proxy

as a general rule.

Furthermore, if your channel is in a faulted state, that means you have .NET exceptions happening on the server-side that don't get caught and handled. In such a case, WCF goes into "panic mode" and basically invalidates the channel - the connection between the client and the server. After all, your server side code just blew up - what's the point in keeping the channel alive??

So on your server-side, you need to make sure you catch and handle all .NET exceptions, and if you want to send them back to the client, convert them to SOAP Faults (FaultException or FaultException<T>) so that they won't thrash the channel. Check out the WCF's IErrorHandler interface for that.

And on your client side, you need to build some logic to check for a faulted channel state, and if it is indeed faulted, toss it away and recreate it from scratch.

Putting all those bits into place, you should have no trouble at all with your WCF services - no hacks like background threads to "keep alive" a connection needed.

marc_s
Thanks a bunch.
Subbu
The design of my application is such that the service host needs to send async messages back to the client. If I were to close the client side proxy, how can I get async call backs from the WCF service? Is there another way in which the service can call back to the client?
Subbu
@Subbu: well, you didn't mention that important bit in your question! If you need duplex communication, then you need to be even more careful about not letting any .NET exceptions cause problems on your channel.
marc_s
Thanks for your advice
Subbu
If I were to close the client proxy after using it, would it be possible for the server to send back messages another way?
Subbu
@Subbu: the callback from the service will happen *before* you get a chance to close the client. It will happen during the service call - once the callback is done, your client call will be over, too, so you can close your client proxy.
marc_s