держать канал обратного вызова wcf открытым неопределенно / повторно соединяться с клиентом, если он выходит из строя - PullRequest
15 голосов
/ 23 марта 2011

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

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

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

В связи с этим у меня возникли следующие вопросы:

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

Я могу придумать нехорошие решения, но я надеюсь, что кто-то здесь скажет мне ПРАВИЛЬНЫЙ способ.*

1 Ответ

15 голосов
/ 23 марта 2011

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...