Socket.io: La forma correcta para que un cliente se vuelva a conectar después de que el servidor haga un socket.disconnect (true)

Creado en 9 mar. 2016  ·  35Comentarios  ·  Fuente: socketio/socket.io

Servidor : nodo + socket.io

var io = require( 'socket.io' )( 3000 );

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

// at some point if client auth fails, server may kick him out:

socket.disconnect( true );

Cliente : html / js + socket.io 1.4.5

socket = io.connect( 'http://127.0.0.1:3000', {
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionDelayMax : 5000,
    reconnectionAttempts: 99999
} );

socket.on( 'connect', function () {
    console.log( 'connected to server' );
} );

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

Lo anterior está simplificado pero esa es la base. La reconexión funciona bien si enciendo el cliente cuando el servidor está inactivo. El cliente intenta conectarse al servidor y cuando finalmente enciendo el servidor, la conexión se establece.

En algún momento puede suceder que el servidor decida desconectar al cliente, principalmente porque se desconectó invalidando el token y una consulta en la base de datos le dice que lo haga, o el token de autenticación expiró o lo que sea.

EN esta circunstancia, me gustaría que el cliente restaure el sondeo del servidor porque el usuario puede querer iniciar sesión nuevamente y tiene los derechos para conectarse nuevamente al servidor.

Si actualizo la página (cliente) en el navegador, funciona bien, pero es una solución desagradable.

Creo que la causa es la propiedad "Manager.skipReconnect" establecida en true después de realizar la desconexión (), por lo que pregunto cuál es la forma correcta de reiniciar un sondeo de reconexión por parte del cliente después de que el servidor desconecta a un cliente.

Encontré algunas respuestas en stackoverflow sobre esto, pero todas no tuvieron éxito, todas las cosas se ejecutarán en el cliente:

  • socket.io.reconnect ();
  • socket.socket.reconnect (); // ??
  • socket = io.connect (' http://127.0.0.1 : 3000', ... // volver a invocar el fragmento de conexión parece una mala idea

¿Podrías ayudarme con este asunto?

Gracias

Comentario más útil

Por ahora, me las arreglé de esta manera y parece ser estable:

Cliente :

var app = {
...
socket: null,
connect: function() {
  var self = this;
  if( self.socket ) {
    self.socket.destroy();
    delete self.socket;
    self.socket = null;
  }
  this.socket = io.connect( 'http://127.0.0.1:3000', {
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionDelayMax : 5000,
    reconnectionAttempts: Infinity
  } );
  this.socket.on( 'connect', function () {
    console.log( 'connected to server' );
  } );
  this.socket.on( 'disconnect', function () {
    console.log( 'disconnected from server' );
    window.setTimeout( 'app.connect()', 5000 );
  } );
}
...
} // var app

Todos 35 comentarios

Por ahora, me las arreglé de esta manera y parece ser estable:

Cliente :

var app = {
...
socket: null,
connect: function() {
  var self = this;
  if( self.socket ) {
    self.socket.destroy();
    delete self.socket;
    self.socket = null;
  }
  this.socket = io.connect( 'http://127.0.0.1:3000', {
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionDelayMax : 5000,
    reconnectionAttempts: Infinity
  } );
  this.socket.on( 'connect', function () {
    console.log( 'connected to server' );
  } );
  this.socket.on( 'disconnect', function () {
    console.log( 'disconnected from server' );
    window.setTimeout( 'app.connect()', 5000 );
  } );
}
...
} // var app

Usando un enfoque similar de:

  this.socket = io.connect( 'ws://127.0.0.1:3000', {
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionDelayMax : 5000,
    reconnectionAttempts: Infinity
  } );

Desafortunadamente, esto hace que el socket utilice el protocolo http, en lugar de los sockets web.

Todavía busco un buen enfoque para una conexión de socket web persistente.

¿Me he perdido algo ???

También interesado en una solución a esto.

socket.connect()
funcionó para mí en la versión 1.5.1. Espero que ayude.

@sconway ¿Puedes iluminarnos? ¿Algún código puede ser?

Hola,

Tenía la misma pregunta, encontré que esta solución, actualmente en prueba, parece ser una solución sólida o una solución alternativa sólida ... (se proporcionan ambas)

http://stackoverflow.com/questions/10437584/socket-io-reconnect

¿Podríamos arreglar esto en socket.io?

Actualicé a la versión 2.0.3 y su configuración de reconexión automática predeterminada funcionó, no hay problemas aquí.

Cuando el servidor o el cliente llaman al método desconectar (), el cliente destruye el socket, elimina todos los controladores de eventos y el administrador lo elimina de la matriz de conexión. Esto no ocurrirá cuando la desconexión sea por otro motivo.
Una gran solución alternativa podría ser leer el parámetro de motivo.
.on('disconnect', reason => { if(reason === 'io server disconnect') { //you should renew token or do another important things before reconnecting socket.connect(); } });
O mucho mejor, verifique si el socket todavía está en la lista de conexiones del administrador
.on('disconnect', () => { if(socket.io.connecting.indexOf(socket) === -1){ //you should renew token or do another important things before reconnecting socket.connect(); } })

¡Lo hice como @DrLightman y funciona perfectamente!

var WebSocketServer = {
    isConnected: false,
    socket: null,
    interval: null,
    connect() {
        if (this.socket) {
            this.socket.destroy();
            delete this.socket;
            this.socket = null;
        }
        this.socket = io.connect('http://localhost:9010', {
            reconnection: false
        });
        this.socket.on('connect', () => {
            this.isConnected = true;
            this.socket.emit('authentication', { user_id: 2751, token: "abc" });
            this.socket.on('authenticated', function() {

            });
        });

        this.socket.on('disconnect', () => {
            this.isConnected = false;
            this.interval = window.setInterval(() => {
                if (this.isConnected) {
                    clearInterval(this.interval);
                    this.interval = null;
                    return;
                }
                WebSocketServer.connect()
            }, 5000);
        });

        return this.socket;
    }
}

var socket = WebSocketServer.connect();

@DrLightman así es como lo hago y funciona perfectamente en navegadores o aplicaciones Android / IOS
var io= new socketio.connect('http://192.168.43.79:3000',{'forceNew':true});

@pablodgonzalez tengo la misma pregunta, ¿tu solución funciona?

@programmerCs Sí, lo es. En producción sin problemas detectados.

Este problema resolvió muchos de mis problemas.
Gracias a todos

Tuve el mismo problema cuando quise forzar a un cliente a actualizar su token porque expiró mientras estaba conectado al servidor.

Terminé enviando un evento al cliente, pidiéndole que actualizara su token. Ningún zócalo se cierra al hacer esto, por lo que evita problemas y funciona bien.

... ¡ahora es el momento de llevar eso a producción! : sudor_frio:: sonrisa satisfecha:

Parece que la solución más simple es escuchar el evento 'desconectar' del emisor y llamar a la función setTimeout (), pero ¿qué pasa con los eventos que el cliente puede crear mientras se desconecta del servidor? Parece que siempre necesita ejecutar una verificación adicional si se establece la conexión antes de transmitir cualquier emisión en el cliente.

@qassa si necesita alguna confirmación sobre emit, debe usar el parámetro de devolución de llamada. En cambio, si necesita garantizar la recepción de un evento, no debe usar socket.io sino alguna biblioteca / protocolo de cola como mosquito / mqtt o lo que sea.
setTimeout es una opción, pero un socket desconectado (por el servidor o el cliente) es un socket que pronto se destruye. Entonces, si necesita garantizar una reconexión fácil y rápida, ¿por qué usar setTimeout si ya tiene la instancia del objeto socket y puede llamar a connect ()?

Alguien del proyecto REALMENTE NECESITA DOCUMENTAR esto ...

Déjame aclarar esto, ¿el servidor desconecta al cliente por una razón específica o debido a una pérdida de conexión a la red? Si es solo una red, entonces Socketio (cliente) intentará indefinidamente volver a conectarse. , si se configura así io=new socketio(‘http://yourserver.com’, {'forceNew':true}); cualquier manera, aún se volverá a conectar, pero si coloca un listerner en una desconexión del servidor, simplemente llame a io.disconnect() en el cliente

De: CxRes [mailto: [email protected]]
Enviado: 01 de febrero de 2018 09:50 PM
Para: socketio / socket.io [email protected]
Cc: devyaz [email protected] ; Comentario [email protected]
Asunto: Re: [socketio / socket.io] La forma correcta para que un cliente se vuelva a conectar después de que el servidor realice un socket.disconnect (verdadero) (# 2476)

Alguien del proyecto REALMENTE NECESITA DOCUMENTAR esto ...

-
Estás recibiendo esto porque hiciste un comentario.
Responda a este correo electrónico directamente, véalo en GitHub https://github.com/socketio/socket.io/issues/2476#issuecomment-362381171 , o silencie el hilo https://github.com/notifications/unsubscribe-auth/ ATfQSQQ1LJ90E6FqsdmiMktpp2AdoLuxks5tQhVQgaJpZM4HsVs7 . https://github.com/notifications/beacon/ATfQSYqwkgtrHZk9FASNZUl69ps9ZYYCks5tQhVQgaJpZM4HsVs7.gif

@devyaz te amo

La documentación se actualizó con la respuesta de @pablodgonzalez : https://github.com/socketio/socket.io-client/commit/afb952d854e1d8728ce07b7c3a9f0dee2a61ef4e

¡Muchas gracias!

Utilice la versión 0.8.3 de io.socket elimine la nueva versión 1.0.0

compile('io.socket:socket.io-client:0.8.3') {
    exclude group: 'org.json', module: 'json'
}

Usando un enfoque similar de:

  this.socket = io.connect( 'ws://127.0.0.1:3000', {
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionDelayMax : 5000,
    reconnectionAttempts: Infinity
  } );

Desafortunadamente, esto hace que el socket utilice el protocolo http, en lugar de los sockets web.

Todavía busco un buen enfoque para una conexión de socket web persistente.

¿Me he perdido algo ???

use wss: //

Usando un enfoque similar de:

  this.socket = io.connect( 'ws://127.0.0.1:3000', {
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionDelayMax : 5000,
    reconnectionAttempts: Infinity
  } );

Desafortunadamente, esto hace que el socket utilice el protocolo http, en lugar de los sockets web.
Todavía busco un buen enfoque para una conexión de socket web persistente.
¿Me he perdido algo ???

use wss: //

hola, hermano. ¿Cómo puede ser que si solo usa wss.it solo funciona como una conexión de socket web persistente, tiene la misma pregunta sobre mantener y reconnet rápido con ws no sondeo?

Cuando el servidor o el cliente llaman al método desconectar (), el cliente destruye el socket, elimina todos los controladores de eventos y el administrador lo elimina de la matriz de conexión. Esto no ocurrirá cuando la desconexión sea por otro motivo.
Una gran solución alternativa podría ser leer el parámetro de motivo.

.on('disconnect', reason => { 
  if(reason === 'io server disconnect') {
    //you should renew token or do another important things before reconnecting
    socket.connect();
  }
});

O mucho mejor, verifique si el socket todavía está en la lista de conexiones del administrador

.on('disconnect',  () => {
  if(socket.io.connecting.indexOf(socket) === -1){
    //you should renew token or do another important things before reconnecting
    socket.connect();
  }
})

¿Puede explicar por qué es mejor verificar si el socket todavía está en la lista de conexiones del administrador? El documento actualizado solo tomó su primera solución, que es verificar el motivo de la desconexión. Gracias.

Hola @emclab , solo porque si en la versión más nueva los desarrolladores agregan alguna razón nueva, y para su caso no es importante "la razón", entonces busque el socket en la lista de conexiones. si no está allí, debe volver a conectarse manualmente.
En algunos casos es importante conocer el motivo, y es el caso más poderoso, leer y actuar en consecuencia pero tal vez no sea el más común.
Descargo de responsabilidad: si opta por la segunda forma, no está a salvo de refactores o algunos cambios en los mecanismos en las versiones más nuevas, por lo que no es mucho mejor pero sí mucho más simple.
¡Saludos!

No puedo desconectar el enchufe en una aplicación iónica. Tengo socket.on en el constructor de una página común en los proveedores. Quiero desconectar el socket en una función en el mismo archivo desde donde se llama al cierre de sesión de la aplicación.

Pero puedo desconectar el enchufe. Soy socket.on múltiple ('evento') en emisión múltiple en la aplicación.
¿Puede alguien ayudarme?

Socket.disconnect () debería hacer

El lunes, 11 de noviembre de 2019 06:16 krunal9421, [email protected] escribió:

No puedo desconectar el enchufe en una aplicación iónica. yo tengo
socket.on en el constructor de una página común en los proveedores. yo quiero
desconecte el socket en una función en el mismo archivo desde donde la aplicación
se llama logout.

Pero puedo desconectar el enchufe. Soy múltiple socket.on ('evento')
en emisión múltiple en la aplicación.
¿Puede alguien ayudarme?

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/socketio/socket.io/issues/2476?email_source=notifications&email_token=AE35ASNI2K4DWOB4P2HPSATQTDMC7A5CNFSM4B5RLM52YY3PNVWWK3TUL52HS4DFVREXWHG43WZMVED ,
o darse de baja
https://github.com/notifications/unsubscribe-auth/AE35ASJPORGOSYQAEJEHHG3QTDMC7ANCNFSM4B5RLM5Q
.

@devyaz No puedo desconectar el enchufe usando socket.disconnect ().
He compartido mi código de muestra con esto.
https://i.stack.imgur.com/wrIEv.png.

He escrito código en un archivo común.

¿Estás intentando desconectarte del servidor o del lado del usuario? es decir, el servidor debería
desconectar al usuario. Porque si el servidor pierde al cliente, dispara una desconexión
evento. Pero el cliente puede desconectarse del servidor llamando
socket.disconnect

El miércoles 20 de noviembre de 2019 a las 05:39 krunal9421, [email protected] escribió:

@devyaz https://github.com/devyaz No puedo desconectar el enchufe
utilizando socket.disconnect ().
He compartido mi código de muestra con esto.
https://i.stack.imgur.com/wrIEv.png.

He escrito código en un archivo común.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/socketio/socket .
o darse de baja
https://github.com/notifications/unsubscribe-auth/AE35ASIFTISGTIAQQ7UKCJDQUSWNVANCNFSM4B5RLM5Q
.

usando esto en el lado del cliente.

Haga this.socketstatus.disconnect() en su función de cierre de sesión y creo
debe eliminar la función ".on (" conectado ", .....)"

El viernes 22 de noviembre de 2019 a las 11:50 krunal9421, [email protected] escribió:

usando esto en el lado del cliente.

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/socketio/socket.io/issues/2476?email_source=notifications&email_token=AE35ASJTREAYRMF4THBK3FDQU6TOLA5CNFSM4B5RLM52YY3PNVWWK3TUL52HS4DFVREXG43VMDVN5H4DFVREXG43VMDVN5Wcom
o darse de baja
https://github.com/notifications/unsubscribe-auth/AE35ASJGKVGVUQNK454C63DQU6TOLANCNFSM4B5RLM5Q
.

Después de perder la conexión, el socket se vuelve a conectar al servidor. Después de eso, sigue mostrando _io.socket.engineio.client.EngineIOException: xhr post error_ en Android .
La mayoría de las respuestas de StackOverflow no funcionan.
Estoy atascado con este problema T_T .... ¡Ayúdame por favor!

Estoy tratando de implementar este código en mi wepapp node.js + javaScript, pero cuando el navegador de mi teléfono está en segundo plano, en una pestaña inactiva o en una pantalla bloqueada, se desconecta después de algunos minutos.

Intenté volver a conectarme a un socket cuando estaba desconectado (con respuestas ping timeout o transport closed ) pero es imposible. ¿Es este un comportamiento normal en los navegadores de teléfonos? porque en los navegadores de computadoras portátiles o de escritorio funciona como se esperaba.

¿Alguien puede ayudarme?

Gracias

Hola @asiermusa pero en web debes usar un web-worker para evitar suspender el proceso. Sinceramente, no sé si es suficiente para lograrlo.

¡salud!

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