Socket.io: ¿Por qué socket.disconnect () en el lado del cliente no activa el evento de desconexión en el servidor?

Creado en 4 nov. 2015  ·  23Comentarios  ·  Fuente: socketio/socket.io

aquí está mi código:

lado del cliente

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

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

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

lado del servidor:

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


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

el método socket.disconnect() no funciona ¿por qué?

Unable to reproduce

Comentario más útil

¿Eres tonto? está esperando una emisión en el cliente pero ninguna emisión en el servidor. Vete a la mierda de aquí

Todos 23 comentarios

Por lo que he probado, funciona bien. ¿Cómo podemos reproducir el problema?

Intente ingresar a la página y recargar rápidamente presionando muchas veces el botón F5.

Funciona bien para mí también.

¿Qué navegador usas? Estoy usando la última versión de Firefox y cuando recargo rápido bage "usuario desconectado" no funciona: decepcionado:

Yo también tengo el problema. En estas acciones, la desconexión, pero llega mucho más tarde que se reinicia el navegador.

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

Hola @ventaquil. Tengo el mismo problema que el evento de desconexión no se dispara cuando se mantiene presionada la tecla F5. ¿Has superado esto?

@ giathinh910 ¿no se activa el evento disconnect después de un retraso determinado (que puede estar relacionado con las opciones pingTimeout / pingInterval , documentadas aquí )?

@darrachequesne Mi problema es el mismo que @ventaquil descrito anteriormente "Intente ingresar a la página y recargue rápidamente presionando muchas veces el botón F5". Por lo general, cuando actualiza una conexión de socket de página, se activará "desconectar" y luego "conectar" nuevamente. Confío en estos 2 eventos para actualizar el número de usuarios en línea. Sin embargo, si la página se recarga lo suficientemente rápido, la "desconexión" no se activará, lo que provocará que se agregue una identificación de socket de usuario inexistente. Estas personas irreales serán eliminadas después de pingTimeout, por supuesto. Actualmente, cambio la forma de guardar la identificación del socket, que solo mostrará al usuario en línea, no el número de socket y el problema se puede resolver.

Manejé este problema de esta manera. Hice un remitente de emisión en el cliente que está llamando al latido del corazón en el servidor.
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); });

Encontré esta función de código para llamar:

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

Esto todavía sucede. No tiene que ser F5/actualizar. Abrir una pestaña y cerrarla rápidamente en una determinada etapa hace que no se active la desconexión. Es difícil de reproducir porque los sockets son muy rápidos, especialmente cuando se ejecutan localmente. Noté que abrir la pestaña en segundo plano y tener otras pestañas abiertas ayudó a reproducir el problema (localmente). Creo que este es un error importante que debe ser abordado.

Tener el mismo problema aquí. Esto es crear juegos de fantasmas en mi servidor de juegos.

Tal vez para desconectar manualmente el cliente, puede usar una función con alguna emisión.
No sé si esto ayudará, pero creo que tengo algo... Tal vez...

Cliente :

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

    socket.close();

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

servidor :

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

Lo siento, pero probablemente dejé algunos agujeros en mi código. no soy profesional 🙁

¡Estoy enfrentando el mismo problema!
Daré el ejemplo en ReactJS-ExpressJS.

Aquí está la situación, que disparará el evento, y está encapsulada en componentWillUnmount() .

Compararé dos eventos, que dispararé desde componentWillUnmount()

  1. newMessage :- esto transmitirá un mensaje a una habitación en particular
  2. disconnect :-(Esperaba que funcionara, pero no funciona) Este detector de eventos tiene una devolución de llamada que se desconectará. He contenido un console.log() solo para confirmar si la devolución de llamada llega.

Ahora, aquí vamos: -
Cliente:-

Estos eventos están siendo disparados: -

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

El siguiente evento no se disparará.

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

Se activará el siguiente evento (solo probando si se emite un evento de mensaje normal)

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

Sin suerte

Servidor:-
Aquí está el código en el backend de expressJS

//Después de initializeChatSocket se llama en 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
      }
    });

  });
}

¿Hay algún problema con el navegador o algo más que deba preguntar a la comunidad de desbordamiento de pila?

@manjotsk No estoy seguro de si ya lo solucionó, pero en el código del lado del servidor está escuchando disconnectt (observe el doble t ) pero su front-end está emitiendo disconnect . Además, probablemente no desee emitir disconnect ya que se supone que ese evento se envía del cliente al servidor cuando el cliente se desconecta.

Tengo un código que se basa en el socket que emite el evento de desconexión para evitar ips duplicados: ¡los usuarios que recargan mi aplicación se bloquean rápidamente porque la desconexión nunca se dispara!

@manjotsk No estoy seguro de si ya lo solucionó, pero en el código del lado del servidor está escuchando disconnectt (observe el doble t ) pero su front-end está emitiendo disconnect . Además, probablemente no desee emitir disconnect ya que se supone que ese evento se envía del cliente al servidor cuando el cliente se desconecta.
¡ disconnectt era un alias impostor que estaba usando! Gracias por señalar. Voy a volver a comprobar con esto en ambos lados. Y, obviamente, ¡la implementación fue incorrecta! ¡Tengo una visión más clara! Gracias @nathanheffley 👍 :)

@manjotsk ¿Qué?

y solo use socket.once en lugar de socket.on
"nivel de cliente".
ejemplo:
socket.on('conectar')
utilizar
socket.once('conectar'
.

igual aquí mi
socket.on("mensaje") { (dataArray, socketAck) -> Anular en

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

no devuelva la devolución de llamada si alguien sabe que me lo diga

¿Eres tonto? está esperando una emisión en el cliente pero ninguna emisión en el servidor. Vete a la mierda de aquí

Esa es una verdadera energía negativa, Ehsan666x.

Manejé este problema de esta manera. Hice un remitente de emisión en el cliente que está llamando al latido del corazón en el servidor.
hbeat[socket.id] = Fecha.ahora();

Me pregunto qué hbeat debería enviarse desde el lado del cliente.

En lugar de socket.disconnect() o socket.emit('disconnect') pruebe socket.close(); en el lado del cliente y debería activar el evento 'disconnect' en el lado del servidor. Funcionó para mí.

¿Fue útil esta página
0 / 5 - 0 calificaciones