WCF: Как определить клиентскую сторону, если сервер отключил меня - PullRequest
16 голосов
/ 30 ноября 2010

У меня есть собственная служба 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. Ницца.

Ответы [ 2 ]

2 голосов
/ 22 октября 2013

Я пошел с Abort-подходом.Казалось, самый логичный метод, и он работает очень хорошо.Клиент получает уведомление о событии Faults в callback-instancecontext.

1 голос
/ 02 марта 2011

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

Так что перед этой строкой кода:

((ICommunicationObject)client.CallbackChannel).Close();
...