2012-03-14 52 views
10

En producción, tengo un juego que usa variables de conexión local para mantener el estado del juego. Sin embargo, observo que si permanezco inactivo durante un cierto tiempo en la conexión, se desconecta y se vuelve a conectar, lo que hace que pierda el estado actual. Durante mis pruebas en un host local, nunca me di cuenta de este comportamiento. ¿Es este el comportamiento normal de las conexiones de socket o hay algo más que hace que las conexiones caigan?NodeJS + Socket.io conexiones cayendo/reconectando?

Si es un comportamiento normal, ¿cómo se maneja esto normalmente? ¿Deben almacenarse los valores de conexión de forma global para que puedan restaurarse si un usuario deja caer/vuelve a conectar?

Respuesta

22

Su problema está relacionado con el tiempo de espera del socket. Si no hay actividad en un determinado socket, socket.io lo cerrará automáticamente.

Una solución fácil (y hackosa) es enviar un latido al cliente conectado para crear actividad y detener el tiempo de espera del socket.

Servidor:

function sendHeartbeat(){ 
    setTimeout(sendHeartbeat, 8000); 
    io.sockets.emit('ping', { beat : 1 }); 
} 

io.sockets.on('connection', function (socket) { 
    socket.on('pong', function(data){ 
     console.log("Pong received from client"); 
    }); 
} 

setTimeout(sendHeartbeat, 8000); 

Cliente:

socket.on('ping', function(data){ 
     socket.emit('pong', {beat: 1}); 
    }); 

Más información:

Puede obtener más información sobre la configuración de socket.io here.

EDIT: Marcos comentó que si el usuario pierde la conexión (la conexión cae en su final debido a problemas de Internet), debería poder restaurar al usuario a su último estado.

Para hacer eso, la mejor manera sería utilizar un método ampliamente utilizado para almacenar datos de usuario, cookies y sesiones.

Un tutorial muy bien hecho sobre cómo hacer esto located here. Aunque utiliza Express para establecer cookies, puedes hacer esto usando cualquier cosa (lo hago usando rieles). Al usar este método, puede almacenar los datos del usuario en una cookie y buscarlos durante el intercambio. Desde allí solo puede acceder a los datos usando socket.handshake.data.

+0

Solución bastante inteligente, gracias :) –

+2

Esta es una solución inteligente pero mantendrá al servidor y al cliente ocupados con ping pong :-(¿alguna otra solución? –

0

Lo que necesita hacer es crear o identificar la sesión por (re) conexión. Puede reducir el número de reconexiones según la respuesta de Moox anterior, pero todavía no es a prueba de fallas, p. un usuario pierde la conexión wifi por un momento, etc. En otras palabras, mantenga los metadatos del usuario por sesión y no por socket, y espere desconexiones y reconexiones ocasionales.

+0

Tienes razón, edité mi pregunta para tomar eso en consideración. – Moox

+0

Lo que he hecho en mi aplicación es mantener los datos de usuario por sesión y no la conexión de socket.io, y administré las sesiones por usuario conecta/desconecta. Lo cual, por cierto, plantea todo el tema de por qué socket.io incluye datos por socket - No creo que esta característica sea realmente "compatible" en la forma en que funciona socket.io. Intenté usarla y abandonarla, debido a las constantes desconexiones/reconexiones. – Mark

Cuestiones relacionadas