Я не использовал NetNamedPipes в WCF, но потратил больше времени, чем хотел, чтобы узнать значения времени ожидания для NetTcp. Я использую следующие конфиги для своих NetTcpBindings и мне повезло, что соединение остается активным.
Сервер:
<binding name="MyBindingName" sendTimeout="00:00:30" receiveTimeout="infinite">
<reliableSession enabled="true" inactivityTimeout="00:05:00" ordered="true" />
<security mode="None" />
</binding>
Клиент:
<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>
Важными настройками, на которые я потратил больше всего времени, являются sendTimeout и receiveTimeout. Если ваш receiveTimeout равен или меньше, чем ваш send, канал будет сброшен, как только истечет время ожидания. Если уровень приема выше, а уровень отправки превышает пороговое значение, канал сработает на уровне активности транспортного уровня. Из моих тестов порог sendTimeout составляет 30 секунд. Все, что меньше этого, и сообщения активности не отправляются.
Кроме того, у меня есть вызов keepalive на основе таймера, который я выполняю каждую минуту, чтобы убедиться, что канал работает и работает нормально. Вызов просто для логического возвращаемого члена:
[OperationContract(IsOneWay = false, IsInitiating = false, IsTerminating = false)]
bool KeepAlive();
public bool KeepAlive()
{
return true;
}
Вы также можете захватить события канала (если вы получили их в нужное время) и повторно открыть соединение, если что-то случится:
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;
}
}
}
Я надеюсь, что некоторые из них будут полезны для NetNamedPipes.
Изменить: дополнительные параметры для захвата перезапущенной проблемы сервера
Когда сервер перезагружается, это должно привести к тому, что клиентский канал закроется или произойдет сбой. Захват этих событий на стороне клиента даст вам возможность использовать таймер переподключения, пока сервис снова не станет доступным.
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;
}
}
Вы хотели бы убедиться, что попытки входа в систему таймера повторного подключения выполняются в фоновом потоке асинхронно, чтобы они не зависали при каждом входе в систему. YMMV