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