2011-03-17 19 views
16

Estamos creando un servidor WCF (.NET 4.0). Solo usará el transporte net.tcp.Detectar desconexión de socket en WCF

Cuando un cliente cierra la conexión TCP, el servidor recibe CommunicationException no administrado y finaliza.

Q1. ¿Cómo manejo la CommunicationException para que el servidor no finalice y continúe prestando servicios a otros clientes?

Q2. En el controlador, ¿cómo obtengo SessionId de la sesión que fue abortada? Necesito esto para limpiar algunos datos específicos de la sesión.

¡Gracias de antemano!

P.S. La conexión es a través de Internet, por lo que el zócalo puede cerrarse en cualquier momento, independientemente de si el cliente se desconecta con elegancia o no.

+0

¿Cuáles son las clases que se está utilizando ? ¿Y qué métodos de las clases estás usando para leer y escribir? Hay un par de clases para manejar conexiones TCP. Solo por nombrar algunos, 'Socket',' TcpClient' –

+1

Los enchufes están ocultos en el interior del marco WCF. En algunos clientes, utilizo la clase genérica System.ServiceModel.ChannelFactory para conectarme al servidor. – Soonts

Respuesta

21

Cualquier canal WCF implementa ICommunicationObject, que proporciona eventos para la duración del canal.

Usted debe escuchar el caso Faulted

El sessionId se puede acceder como siempre de la propiedad OperationContext.Current.

Cuando el cliente abre el canal (en la primera operación), registrarse para los eventos adecuados:

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

y:

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

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

     if (channel != null) 
     { 
      sessionId = channel.SessionId; 
     } 
     [...] 
} 
+2

Esto funciona solo cuando el cliente se cierra con gracia. No funciona cuando el socket se desconecta de repente. – Soonts

+3

si el socket está desconectado, debe obtener un evento de falla de canal. El evento Cerrado se produce cuando el cliente se cierra correctamente, el Faulted cuando es inesperado (como en el caso de una falla de red). – Eilistraee

+2

estos no funcionan cuando transferMode = "Stream" – gordy

-1
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; 
          }); 
        } 

       }); 
Cuestiones relacionadas