Socket.io: pourquoi socket.disconnect() côté client ne déclenche pas d'événement de déconnexion sur le serveur ?

Créé le 4 nov. 2015  ·  23Commentaires  ·  Source: socketio/socket.io

voici mon code:

côté client

 var socket = io.connect('http://' + serverAddress ,{ reconnection: false, forceNew: true  }  );

 socket.emit('monitorAddedNotify' , { video: sourceVideo , socketId: socket.id});

 socket.on('disconnectThatSoc', function(){
    socket.disconnect();
});

du côté serveur:

  io.on('connection', function (socket) {
    console.log('a user connected');


    socket.on('disconnect', function () {
        console.log('user disconnected');
    });
 });

la méthode socket.disconnect() ne fonctionne pas pourquoi ?

Unable to reproduce

Commentaire le plus utile

es-tu stupide? vous attendez une émission sur le client mais pas d'émission sur le serveur. fous le camp d'ici

Tous les 23 commentaires

D'après ce que j'ai testé, ça marche bien. Comment pouvons-nous reproduire le problème ?

Essayez d'entrer dans la page et de recharger rapidement en appuyant plusieurs fois sur le bouton F5.

Cela fonctionne bien pour moi aussi.

Quel navigateur utilisez-vous? J'utilise le dernier Firefox et quand je recharge rapidement bage "utilisateur déconnecté" ne fonctionne pas :déçu:

J'ai le problème aussi. Dans ces actions, déconnexion, mais elle intervient bien plus tard que n'a été redémarré le navigateur.

Navigateur : Chrome 55.0.2883.95 (64 bits)
socket.io : "^1.7.2"

Salut @ventaquil. J'ai le même problème que l'événement de déconnexion ne se déclenche pas lorsque vous maintenez F5. Avez-vous surmonté cela?

@giathinh910 l'événement disconnect n'est-il pas déclenché après un délai donné (qui peut être lié aux options pingTimeout / pingInterval , documentées ici ) ?

@darrachequesne Mon problème est le même que @ventaquil décrit ci-dessus "Essayez d'entrer dans la page et de recharger rapidement en appuyant plusieurs fois sur le bouton F5". Habituellement, lorsque vous actualisez une connexion de socket de page, une connexion se déclenche "déconnecter" puis "connecter" à nouveau. Je compte sur ces 2 événements pour mettre à jour le nombre d'utilisateurs en ligne. Cependant, si la page se recharge assez rapidement, la "déconnexion" ne se déclenchera pas, ce qui entraînera l'ajout d'un identifiant de socket utilisateur inexistant. Ces personnes irréelles seront bien sûr supprimées après pingTimeout. Actuellement, je change la façon d'enregistrer l'identifiant de socket qui ne montrera que l'utilisateur en ligne, pas le numéro de socket et le problème peut être résolu.

J'ai traité ce problème de cette façon. J'ai créé un expéditeur d'émission sur le client qui appelle un battement de coeur sur le serveur.
socket.on("heartbeat", function() { // console.log('heartbeat called!'); hbeat[socket.id] = Date.now(); setTimeout(function() { var now = Date.now(); if (now - hbeat[socket.id] > 5000) { console.log('this socket id will be closed ' + socket.id); if (addedUser) { --onlineUsers; removeFromLobby(socket.id); try { // this is the most important part io.sockets.connected[socket.id].disconnect(); } catch (error) { console.log(error) } } } now = null; }, 6000); });

J'ai trouvé cette fonction de code pour appeler:

io.sockets.connected[socket.id].disconnect();

Cela arrive encore. Il n'est pas nécessaire que ce soit F5/refresh. Ouvrir un onglet et le fermer rapidement à un certain stade empêche la déconnexion de se déclencher. C'est difficile à reproduire car les sockets sont très rapides, surtout lorsqu'ils sont exécutés localement. J'ai remarqué que l'ouverture de l'onglet en arrière-plan et l'ouverture d'autres onglets aidaient à reproduire le problème (localement). Je pense que c'est un bug important qui devrait être corrigé.

Avoir le même problème ici. Ceci crée des jeux fantômes sur mon serveur de jeu

Peut-être que pour déconnecter manuellement le client, vous pouvez utiliser une fonction avec une certaine émission.
Je ne sais pas si ça va aider, mais je pense que j'ai quelque chose... Peut-être...

Client :

function ManualSocketDisconnect() {
    socket.emit("manual-disconnection", socket.id);

    socket.close();

    console.log("Socket Closed. ");
}

Serveur :

io.on("connection", function(socket) {
    console.log("User " + socket.id + " Connected. ");

    socket.on("manual-disconnection", function(data) {
        console.log("User Manually Disconnected. \n\tTheir ID: " + data);
    });
});

Désolé, mais j'ai probablement laissé des trous dans mon code. Je ne suis pas un professionnel. 🙁

Je suis confronté au même problème !
Je vais donner l'exemple dans ReactJS-ExpressJS.

Voici la situation, qui déclenchera l'événement, et est encapsulée dans componentWillUnmount() .

Je vais comparer deux événements, que je déclencherai à partir de componentWillUnmount()

  1. newMessage :- cela diffusera un message dans une pièce particulière
  2. disconnect :-(J'espérais que cela fonctionnerait, mais ce n'est pas le cas) Cet écouteur d'événement a un rappel qui se déconnectera. J'ai contenu un console.log() juste pour confirmer si le rappel arrive.

Maintenant, allons-y: -
Client:-

Ces événements sont déclenchés : -

  componentDidMount() {
    console.log(this.props)
    chat.emit('authenticate', {
      token: localStorage.getItem('auth'),
      refreshToken: localStorage.getItem('refresh'),
      projectId: this.props.projectId,
      userId: this.props.userId,
    });
    chat.on('newMessage', (messageData) => {
      console.log('------------newMessageReceived-------------');
      this.props.messageReceived({ messages: this.props.messages, messageData }, () => {
        console.log('callback');
        this.setState({
          messages: this.props.messages
        })
      })
      console.log(messageData);
    })
  }

L'événement suivant ne se déclenche pas.

  componentWillUnmount() {
    chat.emit('disconnect','just disconnect);
  }

L'événement suivant sera déclenché. (juste tester si un événement de message normal est émis)

  componentWillUnmount() {
    chat.emit('newMEssage', {
      messageHeader: {
        sender: {
          user: {
            id: this.props.userId,
            name: this.props.name
          }
        }
      },
      messageBody: 'hello',
    });
  }

Pas de chance

Serveur:-
Voici le code sur le backend expressJS

// Après initializeChatSocket est appelé dans app.js

function initializeChatSocket(server) {
  projects.hasMany(projectTeam, { foreignKey: 'projectId' });

  const io = socketIO(server);
  const chat = io.of('/chat').on('connection', function (socket) {
    console.log(
      '----------------------------------------New Chat Connection Established-------------------------------------------------------------------------'
    );

    socket.auth = false;

    socket.on('authenticate', function (data) {
      console.log('\n\n\n\n', 'authenticate called', '\n\n\n\n', data, '\n\n\n');

      try {
        const dummyReq = {
          headers: {
            refreshtoken: data.refreshToken,
          },
        };
        console.log('\n\n\n\n', 'before verify', '\n\n\n\n');
        const userDetails = verifyJWTToken(dummyReq, data.token);
        console.log('\n\n\n\n', 'after verify', '\n\n\n\n');
        socket.userId = userDetails.userId;
        socket.projectId = data.projectId;

        projectTeam
          .findAll({
            where: {
              [Op.and]: {
                projectId: data.projectId,
                userId: data.userId,
              }
            }
          })
          .then(projects => {
            console.log('\n\n\n\n', JSON.stringify(projects), '\n\n\n\n');
            if (projects.length === 1) {
              socket.auth = true;
              socket.join(socket.projectId);
              console.log('User id:- ${userDetails.userId} linked to project id :- ${socket.projectId}');
            } else {
              console.log('User id:- ${userDetails.userId} not linked to project id :- ${socket.projectId}');
              throw { message: 'User not linked to project' };
            }
          });
      } catch (error) {
        console.log(String(error));

        socket.auth = false;
        socket.disconnect(String(error));
      }
    });

    socket.on('disconnectt', function() {
      console.log('Client Disconnecting'); // This is not being fired :/
      socket.removeAllListeners('newMessage');
      socket.removeAllListeners('disconnect');
      socket.removeAllListeners('authenticate');
      socket.removeAllListeners('connection');
      });

    socket.on('newMessage', async function (messageData) {
      console.log('-------------------------New Message----------------------', String(messageData));
      //TODO Save Message in Database

      try {
        socket.broadcast.to(socket.projectId).emit('newMessage', messageData);
        console.log('\n\n\n\n\n broadcast sent\n\n' + JSON.stringify(messageData) + '\n\n\n');
      } catch (error) {
        console.log('\n\n\n\n\n broadcast error\n\n\n\n\n');
        console.log(String(error));

        console.log(error);
        //TODO Handle Message Sending Error
      }
    });

  });
}

Est-ce un problème avec le navigateur ou quelque chose d'autre que je dois demander à la communauté stack-overflow ?

@manjotsk Je ne sais pas si vous l'avez déjà corrigé, mais sur votre code côté serveur, vous écoutez disconnectt (remarquez le double t ) mais votre front-end émet disconnect . De plus, vous ne voulez probablement pas émettre disconnect car cet événement est censé être envoyé du client au serveur lorsque le client se déconnecte.

J'ai un code qui repose sur le socket émettant l'événement de déconnexion pour éviter les ips en double - les utilisateurs qui rechargent mon application sont rapidement bloqués car la déconnexion ne se déclenche même jamais !

@manjotsk Je ne sais pas si vous l'avez déjà corrigé, mais sur votre code côté serveur, vous écoutez disconnectt (remarquez le double t ) mais votre front-end émet disconnect . De plus, vous ne voulez probablement pas émettre disconnect car cet événement est censé être envoyé du client au serveur lorsque le client se déconnecte.
disconnectt était un alias d'imposteur que j'utilisais ! Merci de l'avoir signalé. Je revérifierai avec cela des deux côtés. Et, évidemment, la mise en œuvre était erronée ! J'ai une vision plus claire ! Merci @nathanheffley 👍 :)

@manjotsk Quoi ?

et n'utilisez que socket.once au lieu de socket.on
"niveau client".
exemple :
socket.on('connecter')
utiliser
socket.once('connecter'
.

pareil ici mon
socket.on("message") { (dataArray, socketAck) -> Vide dans

  if let data = dataArray.first as? Data{
    do{
      let objc = try JSONDecoder.init().decode(GetChatConversation.self, from: data)
      completionHandler(objc,nil)
    }
    catch let error{
      return completionHandler(nil,error.localizedDescription)
    }
  }else{
    completionHandler(nil,"Cannot cast Array of Any to Data")
  }
}

ne pas rappeler si quelqu'un sait me dire

es-tu stupide? vous attendez une émission sur le client mais pas d'émission sur le serveur. fous le camp d'ici

C'est une véritable énergie négative, Ehsan666x.

J'ai traité ce problème de cette façon. J'ai créé un expéditeur d'émission sur le client qui appelle un battement de coeur sur le serveur.
hbeat[socket.id] = Date.maintenant();

Je me demande quelle hbeat doit être envoyée côté client ?

Au lieu de socket.disconnect() ou socket.emit('disconnect') , essayez socket.close(); côté client et cela devrait déclencher l'événement 'disconnect' côté serveur. Cela a fonctionné pour moi.

Cette page vous a été utile?
0 / 5 - 0 notes