Сохранение канала обратного вызова wcf неограниченно/повторно подключается от клиента, если он неисправен

В настоящее время я пытаюсь настроить что-то вроде этого:

  • служба wcf на стороне сервера зависает и прослушивает через tcp для соединений из службы Windows на стороне клиента.
  • когда соединение получено (клиент вызывает метод CheckIn в службе), служба получает канал обратного вызова через OperationContext.Current.GetCallbackChannel <T>
  • этот канал хранится в коллекции вместе с уникальным ключом (в частности, я храню интерфейс обратного вызова, канал и ключ в списке <ClientConnection> , где каждый из них является свойством). Теперь вызовы
  • теперь могут быть переданы в эту клиентскую службу на основе указанного уникального ключа

это работает сначала, но через некоторое время останавливается - я больше не могу передавать вызовы клиенту. Я предполагаю это, потому что соединение было удалено изнутри, и я пытаюсь работать с мертвым соединением.

что у меня есть следующие вопросы:

  • Как я могу сказать wcf, что я хочу поддерживать эти tcp-соединения неограниченно (или как можно дольше)?
  • Как я могу проверить с клиентской стороны, действительно ли мое соединение с сервером остается действительным, поэтому я могу его сбросить и снова зайти на сервер, если мое соединение обжарено?

Я могу думать о гениальных решениях, но я надеюсь, что кто-то здесь скажет мне правду.

Ответ 1

Когда вы устанавливаете соединение с клиентом, вы должны установить два значения тайм-аута в вашей привязке tcp (привязка, которую вы передадите в ClientBase < > или DuplexClientBase < > ):

NetTcpBinding binding = new NetTcpBinding();
binding.ReceiveTimeout = TimeSpan.FromHours(20f);
binding.ReliableSession.InactivityTimeout = TimeSpan.FromHours(20f);

В моем примере используется 20 часов для тайм-аута, вы можете использовать любое значение, которое имеет смысл для вас. Затем WCF будет пытаться поддерживать ваш клиент и сервер в течение этого периода времени. Значение по умолчанию относительно короткое (возможно, 5 минут?) И может объяснить, почему ваше соединение отключено.

Всякий раз, когда между клиентом и сервером возникает проблема связи (включая сам WCF), WCF будет вызывать событие Faulted в клиенте, с которым вы можете справиться, чтобы делать все, что вам кажется нужным. В моем проекте я передал свой объект DuplexClientBase < > , выделенный для ICommunicationObject, чтобы удержать событие Faulted и перенаправить его в событие OnFaulted, которое было открыто в моем классе:

ICommunicationObject communicationObject = this as ICommunicationObject;
communicationObject.Faulted +=
   new EventHandler((sender, e) => { OnFaulted(sender, e); });

В приведенном выше фрагменте кода this является экземпляром моего типа клиента WCF, который в моем случае получен из DuplexClientBase < > . То, что вы делаете в этом случае, зависит от вашего приложения. В моем случае приложение является некритическим пользовательским интерфейсом, поэтому, если есть ошибка WCF, я просто показываю окно сообщения конечному пользователю и закрываю приложение - это был бы хороший мир, если бы это всегда было так просто