У меня есть отдельная служба WCF с net.tcp DuplexChannel. На сервере я запускаю следующее, чтобы отключить клиента:
((ICommunicationObject)client.CallbackChannel).Close();
Это работает нормально, но как мне определить на клиенте, что он был отключен?
Я подключился к событиям Closed и Faailed как в InstanceContext обратного вызова, так и в канале к серверу:
InstanceContext callback = new InstanceContext(callbackImp);
callback.Closed += new EventHandler(callback_Closed);
и
((ICommunicationObject)Channel).Closed += new EventHandler(Channel_Closed);
Но ничего не работает. Я никогда не получаю уведомления. Обходной путь, который я использую сейчас, заключается в том, чтобы иметь в обратном вызове метод, который вместо этого запускает отключение от клиента. Но я бы предпочел не так поступать. Я особенно не хочу, чтобы сервер ждал отключения пользователя.
РЕДАКТИРОВАТЬ
Я только что понял, что при отключении со стороны клиента я запускаю метод в сервисном контракте, который отмечен IsTerminating = true:
[OperationContract(IsTerminating = true)]
void Disconnect();
Тогда я подумал, что в контракте обратного вызова будет то же самое? Я попытался добавить тот же метод к моему обратному вызову, и он прервал обратный вызов с точки зрения сервера, но я все еще не получил уведомления на стороне клиента ... странно
РЕДАКТИРОВАТЬ
Я узнал еще кое-что информация об этом:
Когда сервер прерывает обратный вызов канал, неисправность возвращается в клиент, клиент ошибается, и мы получаем событие сбоя на клиенте.
Когда сервер закрывает обратный вызов канал, сеанс все еще открыт пока клиент не сообщит о закрытии.
Как только клиент закроет канал вы увидите событие Closed.
Согласно этому утверждению, событие Close не запускается сразу после закрытия callbackchannel с сервера, клиент также должен закрыть его. Таким образом, я мог запустить Close на клиенте в завершающем методе Disconnect обратного вызова. Или я мог бы использовать метод Abort на стороне сервера обратного вызова и пропустить использование метода Disconnect для обратного вызова. Честно говоря, я не знаю, какой из них предпочитаю. Хммм.
РЕДАКТИРОВАТЬ
Я использовал метод прерывания. Это казалось наиболее логичным методом, и он действительно хорошо работает. Клиент получает уведомление о событии Faailed в контексте callback-instancecontext. Хорошо.