Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make Named Pipe binding reconnect automatically in WCF

I'm writing a service that will only get calls from the local host. Performance is important so I thought I'd try the NetNamedPipeBinding instead of NetTcpBinding and see If I could see any noticeable performance gains.

If a client, after having performed one or more requests to the server, is idle for a longer period of time the next request will fail seemingly due to some idle timeout in the binding. The same thing also happens when the service gets restarted.

I need my clients to be able to keep a connection open for as long as it's allowed in order to avoid the overhead associated with setting up a new connection. I also need to be able to restart the service from time to time and have the clients to automatically retry if they notice that the connection has been terminated.

I know that this is suppported by the reliability stuff in NetTcpBinding but how would one go about getting the same level of re-connect reliability in the NetNamedPipeBinding? Is it even possible?

The question is somewhat academic as it isn't a requirement to use NetNamedPipes, I could just as easily adopt it to use the tcp-binding but It's an itch and I'd really like to scratch it.

like image 547
Markus Olsson Avatar asked Dec 04 '08 13:12

Markus Olsson


1 Answers

My experience is that, when using NetNamedPipes, the "ReceiveTimout" on the binding functions like an "Inactivity Timeout" rather than a receive timout. Note that this different than how a NetTCPBinding works. With TCP, it really is a receive timeout and there's a separate inactivity timeout you can configure via reliable messaging. (It's also appears to be contrary to the SDK documentation, but oh well).

To fix this, set the RecieveTimout to something big when you create the binding.
For example, if you are creating your binding procedurally...

NetNamedPipeBinding myBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
myBinding.ReceiveTimeout = TimeSpan.MaxValue;

Or, if you care creating your binding declaratively...

<netNamedPipeBinding>
    <binding name="myBinding" receiveTimeout="infinite">
    </binding>
</netNamedPipeBinding>
like image 115
Matthew Hess Avatar answered Sep 30 '22 21:09

Matthew Hess