Événement de déconnexion de gestion de Socket.IO

88

Je ne peux pas gérer cet événement de déconnexion, je ne sais pas pourquoi le socket n'est pas envoyé au client / client ne répond pas!

Serveur

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;

  });

});

Client

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

        });

    });

Comme vous pouvez le voir lorsqu'un client déconnecte l'objet Array [nom_personne] doit être supprimé, mais ce n'est pas

Raggaer
la source
Vous feriez mieux d'essayer autrement, supprimez d'abord le lecteur puis déconnectez-vous. Parce qu'une fois que vous vous êtes déconnecté du serveur, le serveur ne pourra plus recevoir l'événement émis par le client. Gardez une trace de la prise plutôt que du lecteur, grâce à laquelle vous pouvez facilement supprimer des joueurs.
code-jaff
Comment supprimer le lecteur puis me déconnecter? comment savoir quand le joueur va se déconnecter?.
Raggaer
4
l'événement sur le client ne devrait-il pas être 'disconnect'au lieu de 'disconnected'?
Sherlock
1
@Sherlock dans le code client d'origine d'OP, ils tentaient d'écouter un événement personnalisé qu'ils déclenchaient côté serveur pour une logique déconnectée. «disconnect» est en effet l'événement de déconnexion intégré, mais il ne contribue pas directement au problème qu'ils rencontrent.
Jon Church

Réponses:

170

Ok, au lieu d'identifier les joueurs par nom de piste avec des prises par lesquelles ils se sont connectés. Vous pouvez avoir une implémentation comme

Serveur

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

J'espère que cela vous aidera à penser d'une autre manière

code-jaff
la source
90
Mieux vaut allClients.splice(i, 1)supprimer un élément. delete allClients[i]va juste définir la position du tableau surundefined
Yves
1
Pourquoi cela fonctionne, mais la solution de suivi des personnes avec leurs noms ne fonctionne pas?
sha1
Cela ne fonctionne pas pour moi. Ici ia une valeur de -1 à chaque fois. Pouvez-vous me dire ce qui se passe.
Vinit Chouhan
1
@VinitChouhan, vous devriez probablement poser une question distincte avec votre problème réel.
code-jaff
Lorsque vous obtenez une valeur de -1, cela signifie que vous essayez de raccorder un socket qui n'existe pas (quelqu'un se déconnecte mais vous n'avez pas encore enregistré la personne dans votre allClientstableau). Je vous suggère de revenir: if (i === -1)return;avant d'essayer de le coller.
Koen B.
23

Pour ceux comme @ sha1 se demandant pourquoi le code de l'OP ne fonctionne pas -

La logique d'OP pour supprimer le joueur côté serveur est dans le gestionnaire d' DelPlayerévénement, et le code qui émet cet événement ( DelPlayer) se trouve dans le disconnectedrappel d'événement interne du client.

Le code côté serveur qui émet cet disconnectedévénement se trouve à l'intérieur du disconnectrappel d'événement qui est déclenché lorsque le socket perd la connexion. Puisque le socket a déjà perdu la connexion, l' disconnectedévénement n'atteint pas le client.


La solution acceptée exécute la logique sur l' disconnectévénement côté serveur, qui est déclenché lorsque le socket se déconnecte, fonctionne donc.

TJ
la source
6

Créez une carte ou un ensemble, et en utilisant l'événement "on connection" défini pour chaque socket connecté, en sens inverse l'événement "once disconnect" supprimez ce socket de la carte que nous avons créée précédemment

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

});
Alexander Mills
la source
1
Et on s'attendrait à une réponse détaillée avec des explications et des commentaires d'un vétéran, mais je suppose que nous devons nous contenter d'un paquet de code
Cemal
faites-moi savoir si vous avez des questions, je ne me souviens pas avoir écrit la réponse
Alexander Mills
1
En fait, je n'ai aucune question. C'était juste une critique constructive à un auteur, qui sait mieux utiliser les commentaires et placer la description dans une réponse pour permettre à quiconque (enfin la plupart du moins) de comprendre votre exemple sans vous déranger. Bref, bonne année ..
Cemal
0

Vous pouvez également, si vous le souhaitez, utiliser socket id pour gérer votre liste de joueurs de cette manière.

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)
  })
})
www-data
la source