2012-01-31 9 views
12

Estoy haciendo un simple juego en línea basado en la Web. el juego usa Socket.io para hacer netwoking entre sí. pero encontré el problema.¿Cómo puedo manejar el evento Cerrar en Socket.io?

pensar en la siguiente situación. Ejecuté el servidor Socket.io. un jugador que hace la habitación y otro jugador se une a la sala. jugaron algún juego .. pero un jugador tan enojado y cerró la pestaña del juego.

En esta situación, ¿cómo puedo obtener el evento de que un cliente haya cerrado el navegador en el servidor?

acuerdo con googlear, pueblos dicen así: "El uso de eventos navegador se cierra como onBeforeUnload"

pero sé que todos los navegadores no soportan caso onBeforeUnload. entonces quiero una solución sobre verificando el evento de desconexión del cliente en el lado del servidor.

en Socket.io (nodejs) de la consola del lado del servidor, cuando la conexión del cliente cerrado, la consola como dicen lo siguiente:

de depuración - desechando el transporte

Mi versión 0.4.10 y nodejs es Socket.io la versión es 0.8.7. y ambos se ejecutan en Linux.

¿Alguien puede ayudar, por favor?

códigos shortend están aquí:

var io = require ("socket.io").listen (3335); 
io.sockets.on ("connection" , function (socket) 
{ 
    socket.on ("req_create_room" , function (roomId) 
    { 
    var socketInstance = io 
    .of ("/" + roomId) 
    .on ("connection" , function (sock) 
    { 
     sock.on ("disconnect" , function() 
     { 
      // i want this socket data always displayed... 
      // but first-connected-client doesn't fire this event .. 
      console.log (sock); 
     } 
    }); 
    }); 
}); 
+0

¿Fue útil mi respuesta? ¿Solucionó tu problema? –

Respuesta

7

Hay un evento disconnect que dispara cada vez que una conexión socket.io muere (en cuenta que necesita esto, porque es posible que tenga una página wep abierta, pero lo que si su conexión a Internet muere?). Pruebe esto:

var io = require('socket.io').listen(80); 

io.sockets.on('connection', function (socket) { 
    socket.on('disconnect', function() { 
    io.sockets.emit('user disconnected'); 
    }); 
}); 

en su servidor. Tomado de Socket.IO website.

// EDITAR

Así que miré a su código e hizo algunas pruebas en mi casa. Obtuve los mismos resultados que tú y aquí está mi explicación. Está intentando hacer que Socket.IO sea muy dinámico forzándolo dinámicamente a escuchar diferentes URL (que se agregan en tiempo de ejecución). Pero cuando se realiza la primera conexión, en ese momento el servidor no escucha la otra URL. Parece que exactamente en ese punto (cuando se acepta la conexión) el controlador disconnect está configurado para la primera conexión y no se actualiza más adelante (obsérvese que Socket.IO no crea nuevas conexiones cuando llama al io.connect muchas veces en el lado del cliente) . En general, parece ser un error. O tal vez hay alguna explicación elegante sobre por qué este comportamiento debería ser como es, pero no lo sé.

Déjame decirte algunas otras cosas. En primer lugar, esta creación dinámica de oyentes no parece ser una buena manera. En mi opinión, debe hacer lo siguiente: almacenar las salas existentes y usar una url para todas ellas. Mantenga la ID de una habitación y cuando emita, por ejemplo, message evento del cliente, agregue la ID de una habitación a los datos y maneje esto con un manejador message en el servidor. Creo que entiendes la idea. Inserta la parte dinámica en los datos, no en las URL. Pero podría estar equivocado, al menos esa es mi opinión.

Otra cosa es que el código que escribió parece ser malo. Tenga en cuenta que ejecutar .on('connection', handler) muchas veces lo hará disparar muchas veces. Los manipuladores apilan uno sobre otro, no se reemplazan entre sí. Así que esto es cómo iba a poner en práctica este:

var io = require("socket.io").listen(app); 
var roomIds = []; 

function update_listeners(id) { 
    io.of("/"+id).on("connection", function(socket) { 
     console.log("I'm in room " + id); 
     socket.on("disconnect", function(s) { 
      console.log("Disconnected from " + roomId); 
     });    
    }); 
} 

var test = io.sockets.on("connection", function(socket) { 
    console.log("I'm in global connection handler"); 
    socket.on("req_create_room", function(data) { 
     if (roomIds.indexOf(data.roomId) == -1) { 
      roomIds.push(data.roomId); 
      update_listeners(data.roomId);  
     } 
     test.emit("room_created", {ok:true}); 
    }); 
    socket.on("disconnect", function(s) { 
     console.log("Disconnected from global handler"); 
    }); 
}); 

Tenga en cuenta que el problema con la creación de las conexiones antes de los oyentes se definen seguirá siendo aparecer dentro.

+0

¡Gracias! funciona. pero sigo teniendo algún problema aquí ... en el evento de "desconexión" se desencadena bien pero excepto primer cliente conectado. Quiero saber por qué el primer cliente conectado no puede iniciar el evento de "desconexión". –

+0

No lo sé. Publica un código y lo veremos. – freakish

+0

Publiqué el código. esa es la versión ebridged .. gracias por su ayuda –

17

Actualización: Creé a blog post para esta solución. Cualquier comentario es bienvenido!

Recomiendo usar la opción 'desconexión sincronizada al descargar' para Socket IO. Estaba teniendo problemas similares, y esto realmente me ayudó.

En el cliente:

var socket = io.connect(<your_url>, { 
'sync disconnect on unload': true }); 

No hay necesidad de cables en cualquier de descarga o beforeunload eventos. Probé esto en varios navegadores, y funcionó perfectamente hasta ahora.

+1

Señor, me alegraste el día. ¡He perdido 7 horas tratando de encontrar una solución a este problema! –

+0

Vincular a la publicación en lugar del blog – laggingreflex

+0

He actualizado la URL del enlace. –

Cuestiones relacionadas