Обработка отложенных клиентов в приложении WCF для двусторонней привязки

Мы используем модель pub-sub в нашем приложении WCF, которое в значительной степени следует за образцом Microsoft: Шаблоны проектирования: Публикация-Подписка на основе списков.

В то время как служба предоставляет понятие subscribe() и unsubscribe(), какова наилучшая практика для обработки очистки в ситуации, когда клиент умирает или неисправности канала? В настоящее время, когда клиент подписывается, я присоединяюсь к обработчикам к текущим событиям InstanceContext Closed и Faulted (пользователи службы используют режим контекста экземпляра PerSession и netTcpBinding):

_communicationObject = OperationContext.Current.InstanceContext;
_communicationObject.Closed += OnClientLost;
_communicationObject.Faulted += OnClientLost;

Обработчик OnClientLost просто отписывает клиента:

  • Является ли вышеприведенная практика и достаточно сильной, чтобы поймать все ситуации, когда клиент отключает двустороннюю связь? Или служба должна просто обрабатывать исключения, встречающиеся в точке, где она пытается связаться с клиентом и обрабатывать очистку тогда?
  • Помимо просто отмены подписки на обработчик обратного вызова клиента, следует ли выполнить любую дополнительную очистку, особенно в случае неисправности?

Этот вопрос ставит аналогичный вопрос, но в конечном итоге не дает ответов на случаи, находящиеся за пределами клиента, вызывая подписку и/или отмену подписки

Спасибо

Ответы

Ответ 1

Я провел некоторое тестирование, где я привязал обработчики к событиям Closed и Faulted канала обратного вызова, а затем убил клиента в точке непосредственно перед вызовом вызывающего сервера сервером. В каждом испытании событие Closed/Faulted было запущено мгновенно и до того, как сервер попытался вызвать обратный вызов. Тем не менее, у меня все еще есть вызов обратного вызова, завернутый в блок try-catch, потому что уничтожение клиентского канала может происходить так же, как другой поток вводит обратный вызов.

Единственной необходимой очисткой было удаление ссылки на канал обратного вызова. WCF и сборщик мусора делают все остальное.

Ответ 2

Обработка этих событий позволит синхронизировать список подписчиков. Это действительно достаточно устойчиво. Просто помните, что если клиент падает во время передачи сообщения, вы можете получить исключение до того, как эти события будут гореть, поэтому будьте готовы игнорировать их, чтобы события могли очищаться.

За исключением удаления клиента из списка подписчиков, дополнительная очистка полностью зависит от вашего приложения (т.е. освобождения ресурсов, которые вы приобрели при подключении клиента). Я не знаю никакой другой очистки, которая требуется.