Socket.IO che gestisce l'evento di disconnessione


88

Non posso gestire questo evento di disconnessione, non so perché il socket non viene inviato al client / client non risponde!

server

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

        });

    });

Come puoi vedere quando un client disconnette l'oggetto Array [person_name] dovrebbe essere cancellato, ma non lo è


È meglio provare in un altro modo, eliminare prima il lettore e poi disconnettersi. Perché una volta disconnesso dal server, il server non sarà in grado di ricevere l'evento emesso dal client. Tieni traccia della presa piuttosto che del lettore, grazie al quale puoi rimuovere facilmente i giocatori.
code-jaff

Come devo eliminare il lettore e poi disconnettermi? come faccio a sapere quando il lettore si disconnetterà ?.
Raggaer

4
non dovrebbe essere l'evento sul client 'disconnect'invece di 'disconnected'?
Sherlock

1
@Sherlock nel codice client originale di OP stavano tentando di ascoltare un evento personalizzato che stavano attivando lato server per logica disconnessa. "disconnect" è effettivamente l'evento di disconnessione integrato, ma non contribuisce direttamente al problema che stanno riscontrando.
Jon Church

Risposte:


170

Ok, invece di identificare i giocatori per nome traccia con le prese attraverso cui si sono collegati. Puoi avere un'implementazione come

server

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

Spero che questo ti aiuti a pensare in un altro modo


90
Uso migliore allClients.splice(i, 1)per eliminare un elemento. delete allClients[i]imposterà semplicemente la posizione dell'array suundefined
Yves

1
Perché funziona, ma la soluzione di monitoraggio delle persone con i loro nomi non funziona?
sha1

Questo non funziona per me. Qui iha un valore di -1 ogni volta. Puoi dirmi cosa sta succedendo.
Vinit Chouhan

1
@VinitChouhan dovresti probabilmente fare una domanda separata con il tuo problema reale.
code-jaff

Quando ottieni un valore di -1, significa che stai cercando di unire un socket che non esiste (qualcuno si disconnette ma non hai ancora registrato la persona nel tuo allClientsarray). Ti consiglio di tornare: if (i === -1)return;prima di provare a giuntarlo.
Koen B.

23

Per quelli come @ sha1 che si chiedono perché il codice dell'OP non funziona -

La logica di OP per l'eliminazione del giocatore sul lato server è nel gestore DelPlayerdell'evento e il codice che emette questo evento ( DelPlayer) è nel disconnectedcallback dell'evento interno del client.

Il codice lato server che emette questo disconnectedevento è all'interno del disconnectcallback dell'evento che viene attivato quando il socket perde la connessione. Poiché il socket ha già perso la connessione, l' disconnectedevento non raggiunge il client.


La soluzione accettata esegue la logica disconnectsull'evento sul lato server, che viene attivato quando il socket si disconnette, quindi funziona.


6

Crea una mappa o un set e, utilizzando l'evento "alla connessione" impostato su ogni socket connesso, al contrario l'evento "una volta disconnesso" elimina quel socket dalla mappa che abbiamo creato in precedenza

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
E ci si aspetterebbe una risposta dettagliata con spiegazioni e commenti da un veterano, ma immagino che dobbiamo accontentarci solo di un mucchio di codice
Cemal

fammi sapere se hai domande, non ricordo di aver scritto la risposta
Alexander Mills

1
In realtà non ho nessuna domanda. Era solo una critica costruttiva a un autore, che sa usare meglio i commenti e inserire la descrizione in una risposta per permettere a chiunque (beh, almeno) di capire il tuo esempio senza disturbarti. Comunque, felice anno nuovo ..
Cemal

0

Puoi anche, se ti piace, usare il socket id per gestire la tua lista di giocatori in questo modo.

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)
  })
})
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.