I haven't used NetNamedPipes in WCF but I spent more time than I cared to learning the timeout values for NetTcp. I use the following configs for my NetTcpBindings and had good luck with the connection staying active.
Server:
<binding name="MyBindingName" sendTimeout="00:00:30" receiveTimeout="infinite">
<reliableSession enabled="true" inactivityTimeout="00:05:00" ordered="true" />
<security mode="None" />
</binding>
Client:
<binding name="MyBindingName" closeTimeout="00:00:30" openTimeout="00:00:30" receiveTimeout="infinite" sendTimeout="00:00:30">
<reliableSession enabled="true" inactivityTimeout="00:01:00" ordered="true" />
<security mode="None" />
</binding>
The important settings that I spent the most time on are the sendTimeout and receiveTimeout. If your receiveTimeout is the same or less than your send, the channel will drop once that timeout is reached. If the receive is higher and the send is above a threshold, the channel will fire a transport level keepalive. From my tests, the sendTimeout threshold is 30 seconds. Anything less than that and the keepalives aren't sent.
Additionally, I have a timer based keepalive call that I execute every minute to try and ensure the channel is up and working well. The call is simply to a boolean return member:
[OperationContract(IsOneWay = false, IsInitiating = false, IsTerminating = false)]
bool KeepAlive();
public bool KeepAlive()
{
return true;
}
You can also grab the channel events (if you get them at the right time) and reopen the connection if something bad happens:
InstanceContext site = new InstanceContext(this);
_proxy = new MyServiceChannel(site);
if (_proxy != null)
{
if (_proxy.Login())
{
//Login was successful
//Add channel event handlers so we can determine if something goes wrong
foreach (IChannel a in site.OutgoingChannels)
{
a.Opened += Channel_Opened;
a.Faulted += Channel_Faulted;
a.Closing += Channel_Closing;
a.Closed += Channel_Closed;
}
}
}
I hope some of this translates and has value for you with NetNamedPipes.
Edit: More options for capturing the server restarted issue
When the server restarts it should cause the client's channel to either close or fault. Capturing those events on the client side would give you the option of using reconnect timer until the service is available again.
private void Channel_Faulted(object sender, EventArgs e)
{
IChannel channel = sender as IChannel;
if (channel != null)
{
channel.Abort();
channel.Close();
}
//Disable the keep alive timer now that the channel is faulted
_keepAliveTimer.Stop();
//The proxy channel should no longer be used
AbortProxy();
//Enable the try again timer and attempt to reconnect
_reconnectTimer.Start();
}
private void _reconnectTimer_Tick(object sender, System.EventArgs e)
{
if (_proxy == null)
{
InstanceContext site = new InstanceContext(this);
_proxy = new StateManagerClient(site);
}
if (_proxy != null)
{
if (_proxy.Login())
{
//The connection is back up
_reconnectTimer.Stop();
_keepAliveTimer.Start();
}
else
{
//The channel has likely faulted and the proxy should be destroyed
AbortProxy();
}
}
}
public void AbortProxy()
{
if (_proxy != null)
{
_proxy.Abort();
_proxy.Close();
_proxy = null;
}
}
You would want to ensure the reconnect timer's login attempts are done on a background thread asynchronously so they don't hang the UI every time they attempt to login. YMMV