Обнаружить разъединение разъема в WCF - PullRequest
16 голосов
/ 17 марта 2011

Мы создаем сервер WCF (.NET 4.0).Он будет использовать только транспорт net.tcp.

Когда клиент закрывает TCP-соединение, сервер получает необработанное исключение CommunicationException и завершает работу.

Q1.Как мне обработать CommunicationException, чтобы сервер не завершал работу и продолжал обслуживать других клиентов?

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

Заранее спасибо!

PS Соединение установлено через Интернет, поэтому сокет может быть закрыт в любое время, независимо от того, является ли клиентотключается изящно или нет.

Ответы [ 2 ]

22 голосов
/ 17 марта 2011

Любой канал WCF реализует ICommunicationObject , который предоставляет события для времени жизни канала.

Вы должны прослушать событие Failed

Идентификатор сессии можно получить как всегда из свойства OperationContext.Current .

Когда ваш клиент откроет канал (при первой операции), зарегистрируйтесь на соответствующие события:

OperationContext.Current.Channel.Faulted += new EventHandler(Channel_Faulted);
OperationContext.Current.Channel.Closed += new EventHandler(Channel_Faulted);

и

 void Channel_Faulted(object sender, EventArgs e)
 {
     Logout((IContextChannel)sender);
 }

 protected void Logout(IContextChannel channel)
 {
        string sessionId = null;

        if (channel != null)
        {
            sessionId = channel.SessionId;
        }
      [...]
 }
0 голосов
/ 03 июля 2015
ICommunicationObject obj = (ICommunicationObject)callback;
                obj.Closed += new EventHandler((a, b) => 
                {
                    if (list.Exists(cli => cli.CallbackService == (ITecnobelRemoteServiceCallback)a))
                    {
                        var query = (from cc in list where cc.CallbackService == (ITecnobelRemoteServiceCallback)a select cc).ToList();
                        query.ForEach(
                            delegate (Client ccc)
                            {
                                ccc.CallbackService = null;
                            });
                    }

                });
...