Evento de desconexión de manejo de Socket.IO


88

No puedo manejar este evento de desconexión, ¡no sé por qué el socket no se envía al cliente / cliente no responde!

Servidor

io.sockets.on('connection', function (socket) {

  socket.on('NewPlayer', function(data1) {

    online = online + 1;
    console.log('Online players : ' + online);
    console.log('New player connected : ' + data1);
    Players[data1] = data1;
    console.log(Players);

  });

  socket.on('DelPlayer', function(data) {

    delete Players[data];
    console.log(Players);
    console.log('Adios' + data);

  });

  socket.on('disconnect', function () {

      socket.emit('disconnected');
      online = online - 1;

  });

});

Cliente

 var socket = io.connect('http://localhost');

    socket.on('connect', function () { 

        person_name = prompt("Welcome. Please enter your name");

        socket.emit('NewPlayer', person_name);

        socket.on('disconnected', function() {

            socket.emit('DelPlayer', person_name);

        });

    });

Como puede ver, cuando un cliente desconecta el objeto Array, [person_name] debe eliminarse, pero no


Será mejor que intente al revés, primero elimine el reproductor y luego desconecte. Porque una vez que se haya desconectado del servidor, el servidor no podrá recibir el evento que emite el cliente. Realice un seguimiento del zócalo en lugar del reproductor, mediante el cual puede eliminar reproductores fácilmente.
code-jaff

¿Cómo debo eliminar el reproductor y luego desconectarme? ¿Cómo sé cuándo se desconectará el reproductor?
Raggaer

4
¿No debería ser el evento en el cliente en 'disconnect'lugar de 'disconnected'?
Sherlock

1
@Sherlock en el código de cliente original de OP, estaban intentando escuchar un evento personalizado que estaban activando en el servidor por lógica desconectada. 'desconectar' es de hecho el evento de desconexión integrado, pero no contribuye directamente al problema que están experimentando.
Jon Church

Respuestas:


170

De acuerdo, en lugar de identificar a los jugadores por pista de nombre con enchufes a través de los cuales se han conectado. Puedes tener una implementación como

Servidor

var allClients = [];
io.sockets.on('connection', function(socket) {
   allClients.push(socket);

   socket.on('disconnect', function() {
      console.log('Got disconnect!');

      var i = allClients.indexOf(socket);
      allClients.splice(i, 1);
   });
});

Espero que esto te ayude a pensar de otra manera.


90
Mejor uso allClients.splice(i, 1)para eliminar un elemento. delete allClients[i]establecerá la posición de la matriz enundefined
Yves

1
¿Por qué funciona, pero la solución de seguimiento de personas con sus nombres no funciona?
sha1

Esto no me funciona. Aquí itiene un valor de -1 cada vez. ¿Puedes decirme qué está pasando?
Vinit Chouhan

1
@VinitChouhan probablemente debería hacer una pregunta separada con su problema real.
code-jaff

Cuando obtiene un valor de -1, significa que está intentando empalmar un socket que no existe (alguien se desconecta pero aún no ha registrado a la persona en su allClientsmatriz). Te sugiero que regreses if (i === -1)return;antes de intentar empalmarlo.
Koen B.

23

Para aquellos como @ sha1 que se preguntan por qué el código del OP no funciona:

La lógica de OP para eliminar el jugador en el lado del servidor está en el controlador del DelPlayerevento, y el código que emite este evento ( DelPlayer) está en la disconnecteddevolución de llamada del evento interno del cliente.

El código del lado del servidor que emite este disconnectedevento está dentro de la disconnectdevolución de llamada del evento que se activa cuando el socket pierde la conexión. Dado que el socket ya perdió la conexión, el disconnectedevento no llega al cliente.


La solución aceptada ejecuta la lógica del disconnectevento en el lado del servidor, que se activa cuando el socket se desconecta, por lo tanto, funciona.


6

Cree un mapa o un conjunto, y usando el evento "en conexión" establecido en cada enchufe conectado, a la inversa, el evento "una vez desconectado" elimine ese enchufe del mapa que creamos anteriormente.

import * as Server from 'socket.io';

const io = Server();
io.listen(3000);

const connections = new Set();

io.on('connection', function (s) {

  connections.add(s);

  s.once('disconnect', function () {
    connections.delete(s);
  });

});

1
Y uno esperaría una respuesta detallada con explicaciones y comentarios de un veterano, pero supongo que tenemos que conformarnos con solo un montón de código
Cemal

avíseme si tiene preguntas, no recuerdo haber escrito la respuesta
Alexander Mills

1
De hecho, no tengo ninguna pregunta. Fue solo una crítica constructiva para un autor, que sabe mejor cómo usar los comentarios y colocar la descripción en una respuesta para permitir que cualquiera (bueno, al menos) entienda su ejemplo sin molestarlo. De todos modos, feliz año nuevo ..
Cemal

0

También puede, si lo desea, usar el ID de socket para administrar su lista de jugadores de esta manera.

io.on('connection', function(socket){
  socket.on('disconnect', function() {
    console.log("disconnect")
    for(var i = 0; i < onlineplayers.length; i++ ){
      if(onlineplayers[i].socket === socket.id){
        console.log(onlineplayers[i].code + " just disconnected")
        onlineplayers.splice(i, 1)
      }
    }
    io.emit('players', onlineplayers)
  })

  socket.on('lobby_join', function(player) {
    if(player.available === false) return
    var exists = false
    for(var i = 0; i < onlineplayers.length; i++ ){
      if(onlineplayers[i].code === player.code){
        exists = true
      }
    }
    if(exists === false){
      onlineplayers.push({
        code: player.code,
        socket:socket.id
      })
    }
    io.emit('players', onlineplayers)
  })

  socket.on('lobby_leave', function(player) {
    var exists = false
    for(var i = 0; i < onlineplayers.length; i++ ){
      if(onlineplayers[i].code === player.code){
        onlineplayers.splice(i, 1)
      }
    }
    io.emit('players', onlineplayers)
  })
})
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.