Socket.io: Excepciones de JS lanzadas mientras está inactivo (WebSocket ya está en estado de CIERRE o CERRADO).

Creado en 26 may. 2018  ·  55Comentarios  ·  Fuente: socketio/socket.io

Tú quieres:

  • [x] informar de un error
  • [ ] solicitar una función

Comportamiento actual

Mientras dejo un socket conectado, pero no realizo ninguna otra actividad en mi programa, veo de manera intermitente (pero bastante consistente) una excepción lanzada en la consola del navegador, desde el interior de la maquinaria socket.io (específicamente en backo2/index.js línea 83. Ese error es:

WebSocket is already in CLOSING or CLOSED state.

socket-io-errors

Pasos para reproducir (si el comportamiento actual es un error)

Tengo dos pestañas abiertas con sockets de clientes conectados al mismo servidor (localhost) a través de https. Ambos clientes están inactivos sin que suceda nada más en el navegador o el servidor (a excepción de los pings de mantenimiento que está haciendo socket.io). Ambos están unidos a un solo canal (a través join(..) en el servidor). Por lo demás, nada más especial.

Así es como creo la instancia del socket del servidor:

var httpsServer = https.createServer(..);
var io = require("socket.io")(httpsServer);
io.on("connection",onSocketConnection);

Y en el cliente:

socket = io();
socket.on("connect",function(){
   console.log("socket connected");
});
socket.on("disconnect",function(){
   console.log("socket disconnected");
});

Comportamiento esperado

Espero desconexiones y reconexiones de vez en cuando, pero no espero excepciones JS falsas lanzadas por la biblioteca cuando no estoy haciendo nada más sobre las conexiones.

Configuración

  • SO: MacOSX
  • navegador: Chrome 66, nodo 10.2.1
  • versión socket.io: 2.1.1

Otra información (p. ej., stacktraces, problemas relacionados, sugerencias sobre cómo solucionarlos)

Rastreo de pila ampliado:

index.js:83 WebSocket is already in CLOSING or CLOSED state.
(anonymous) @ index.js:83
e.encodePacket @ index.js:83
(anonymous) @ index.js:83
r.write @ index.js:83
r.send @ index.js:83
r.flush @ index.js:83
r.sendPacket @ index.js:83
r.ping @ index.js:83
(anonymous) @ index.js:83
setTimeout (async)
r.setPing @ index.js:83
r.onPacket @ index.js:83
(anonymous) @ index.js:83
r.emit @ index.js:83
r.onPacket @ index.js:83
r.onData @ index.js:83
ws.onmessage @ index.js:83

Comentario más útil

Hay un cambio para el pingTimeout predeterminado de 60000 (v2.0.4) a 5000 (v2.1.0+) que no es suficiente para algunos navegadores como Chrome.

La solución a este problema en v2.1.0+, incluida la última v2.2.0, es anular el pingTimeout predeterminado en su servidor a un valor grande de la siguiente manera:

const http = require('http');
const server = http.createServer();
const io = require('socket.io')(server, {
  pingTimeout: 60000,
});

O

const io = require('socket.io')();
const http = require('http');
const server = http.createServer();
io.attach(server, {
  pingTimeout: 60000,
});

Todos 55 comentarios

Experimentando absolutamente el mismo problema y el código es correcto. Esto solo sucede en Chrome para mí. Mozilla está limpio. En chrome me esta lloviendo este err una y otra vez y duplicando todos los chats que tengo. Intenté usar este método
socket.on('disconnect', () =>{ socket.disconnect(); });
No desconecta al cliente del servidor. Repo en caso de que sea necesario https://github.com/antoniab123456/Chat_app

el mismo problema aqui
image

el navegador está inactivo, luego aparecen los errores.

Usé Chrome y Mac OS

Sí chicos, ¿alguien puede abordar eso? ¿Quizás necesitamos otra línea de código para arreglar eso?

Tengo el mismo problema con socket.io y Chrome
Mac OS 10.13.5
Versión de Chrome 67.0.3396.87 (compilación oficial) (64 bits)
Nodo: 10.3.0
Expreso: 4.16.3
socket.io: 2.1.1

En Firefox todo está bien.

Detalles del error a continuación:

index.js:83 WebSocket is already in CLOSING or CLOSED state.
(anonymous) | @ | index.js:83
  | e.encodePacket | @ | index.js:83
  | (anonymous) | @ | index.js:83
  | r.write | @ | index.js:83
  | r.send | @ | index.js:83
  | r.flush | @ | index.js:83
  | r.sendPacket | @ | index.js:83
  | r.ping | @ | index.js:83
  | (anonymous) | @ | index.js:83
  | setTimeout (async) |   |  
  | r.setPing | @ | index.js:83
  | r.onPacket | @ | index.js:83
  | (anonymous) | @ | index.js:83
  | r.emit | @ | index.js:83
  | r.onPacket | @ | index.js:83
  | r.onData | @ | index.js:83
  | ws.onmessage | @ | index.js:83

Cuando hago clic en index.js:83 me lleva a este módulo:

/**
 * Expose `Backoff`.
 */

module.exports = Backoff;

/**
 * Initialize backoff timer with `opts`.
 *
 * - `min` initial timeout in milliseconds [100]
 * - `max` max timeout [10000]
 * - `jitter` [0]
 * - `factor` [2]
 *
 * <strong i="16">@param</strong> {Object} opts
 * <strong i="17">@api</strong> public
 */

function Backoff(opts) {
  opts = opts || {};
  this.ms = opts.min || 100;
  this.max = opts.max || 10000;
  this.factor = opts.factor || 2;
  this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
  this.attempts = 0;
}

/**
 * Return the backoff duration.
 *
 * <strong i="18">@return</strong> {Number}
 * <strong i="19">@api</strong> public
 */

Backoff.prototype.duration = function(){
  var ms = this.ms * Math.pow(this.factor, this.attempts++);
  if (this.jitter) {
    var rand =  Math.random();
    var deviation = Math.floor(rand * this.jitter * ms);
    ms = (Math.floor(rand * 10) & 1) == 0  ? ms - deviation : ms + deviation;
  }
  return Math.min(ms, this.max) | 0;
};

/**
 * Reset the number of attempts.
 *
 * <strong i="20">@api</strong> public
 */

Backoff.prototype.reset = function(){
  this.attempts = 0;
};

/**
 * Set the minimum duration
 *
 * <strong i="21">@api</strong> public
 */

Backoff.prototype.setMin = function(min){
  this.ms = min;
};

/**
 * Set the maximum duration
 *
 * <strong i="22">@api</strong> public
 */

Backoff.prototype.setMax = function(max){
  this.max = max;
};

/**
 * Set the jitter
 *
 * <strong i="23">@api</strong> public
 */

Backoff.prototype.setJitter = function(jitter){
  this.jitter = jitter;
};




//////////////////
// WEBPACK FOOTER
// ./~/backo2/index.js
// module id = 41
// module chunks = 0

La línea 83 es:

this.jitter = jitter;

Tengo el mismo problema, con backo2.js y en la línea 83. Aquí está mi error:
index.js:83 TypeError no detectado: no se pudo ejecutar 'readAsArrayBuffer' en 'FileReader': el parámetro 1 no es del tipo 'Blob'.
en n (index.js:83)
en n (index.js:83)
en n (index.js:83)
en n (index.js:83)
en n (index.js:83)
en n (index.js:83)
en Object.e.removeBlobs (index.js:83)
en s (index.js:83)
en r.encode (index.js:83)
en r.packet (index.js:83)
y no te preocupes por las otras cosas, todas están en la línea 83, que es this.jitter = jitter;
Me molesta tanto porque no hay realmente ninguna solución en Google.

¿Alguien ha encontrado una solución temporal? @antoniab123456 ¿pudiste arreglar tu aplicación de chat para que no duplique tus chats? Me esta haciendo lo mismo.

Configuración
SO: MacOSX
Navegador: Chrome 67.0.3396.99 (compilación oficial) (64 bits)
Nodo v10.5.0
Zócalo.io v2.1.1

Estoy enfrentando el problema exacto que @getify mencionó en Chrome. ¿Alguien ha encontrado alguna solución para esto?

El mismo problema. ¿Puede alguien responder a esto?

El mismo problema.

Configuración
SO: MacOSX
navegador: Chrome 67.0.3396.99 (compilación oficial) (64 bits), nodo 9.6.1
versión socket.io: 2.1.1

@ 19smitgr idk lo que quiere decir con 'chats duplicados' que suena fuera de tema que podría resolverse transmitiendo en su lugar si quiere decir 'mensaje duplicado en la misma pantalla'.

@kino2007 No estoy creando una aplicación de chat. De hecho, estoy usando websockets con un juego multijugador, y el websocket no recibía un mensaje de desconexión, así que cuando el usuario se desconectó y se volvió a conectar debido al error aleatorio del que todos hablan, le daría al personaje una nueva ID de socket, y el sprite anterior con la ID de socket anterior no se eliminó porque solo estaba recibiendo un mensaje de "cierre de transporte" en lugar de un mensaje de "desconexión".

En este punto, incluso si recibo un mensaje de "cierre de transporte", simplemente elimino al usuario de mi lista de usuarios actuales de la misma manera que si recibiera un mensaje de "desconexión".

Mismo error aquí

Después de una búsqueda rápida, descubrí que backo2 causa el error.

Luego usé la versión de desarrollo de socket.io y descubrí que Socket.prototype.onevent arroja el error.

Lo arreglé para mí:

Anteriormente usé esto:

socket.on('ping', alert);

Pero luego lo cambié a esto:

socket.on('ping', msg => {
    alert(msg);
});

¡Y funcionó!

Estoy teniendo el mismo problema. ¿Alguna actualización sobre esto?

Aquí igual.

socket.io & socket.io-cliente: "^2.1.1"
Mac OS
Google Chrome está actualizado
Versión 68.0.3440.106 (compilación oficial) (64 bits)

Tengo el mismo problema. Además, está duplicando los mensajes que envío del servidor al cliente.

screen shot 2018-08-30 at 4 51 49 pm

MacOS: 10.13.6
Zócalo.io: "^2.1.1"
cromo: 68.0.3440.106

@abhyuditjain Puede intentar restablecer todos los oyentes usando socket.removeAllListeners(); para evitar múltiples registros de oyentes que podrían causar la duplicación de mensajes.

Esto parece ser un problema continuo para varias personas y no ha habido ninguna solución para esto. ¿Alguna actualización de alguien?

@vkotu Si elimino todos los oyentes, entonces el socket no se vuelve a conectar al servidor al desconectarse. Cualquier forma de arreglar esto?

no es un anuncio, solo ayuda, a menos que tenga una decisión sobre este error: DDD ha estado sucediendo durante meses 09/05/2018, 13:15, "Abhyudit Jain" [email protected] : @antoniab123456 Esta página es para publicar problemas sobre esto repositorio. Por favor, no haga publicidad por aquí.

—Estás recibiendo esto porque te mencionaron. Responde a este correo electrónico directamente, míralo en GitHub o silencia el hilo.

-- Atentamente, Antonia B. Especialista en atención al cliente @amoCRM Global

Bajar de categoría a 2.0.3 "arregló" este problema para mí.

@cozuya va a probarlo. ¡Te dejaré saber si funcionó!

Bajar de categoría a 2.0.3 "arregló" este problema para mí.

parece estar haciendo el truco. Probado durante 4 minutos y sin errores. ¡A ver cuánto aguanta!

@cozuya gracias por publicar esto!

Mismo error en 2.1.1

Bajar de categoría a 2.0.3 "arregló" este problema para mí.

¡2.0.3 funciona para mí! Gracias @cozuya

2.1.1 todavía enfrenta los mismos problemas. Intenté aumentar el ping y el tiempo de espera, pero nada cambió

teniendo el mismo problema en Chrome con v2.1.1, mientras el navegador está inactivo durante mucho tiempo (alrededor de 20-30 minutos)

2.1.1 todavía enfrenta los mismos problemas. Intenté aumentar el ping y el tiempo de espera, pero nada cambió

degradar a v 2.0.3

He intentado usar socket.io con 2.0.4, parece normal.

Descubrí que hay un cambio para el pingTimeout de 60000 (v2.0.4) a 5000 (v2.1.1)

Si he cambiado pingTimeout a un número mayor como 10000, parece funcionar.

Supongo que puede estar relacionado con el navegador inactivo donde la pestaña inactiva tendrá algo de aceleración.

Tuve un problema. ¿Alguien resolvió el problema?

Tuve que bajar de categoría también. No funcionaba para Chrome y Safari.

El mismo problema aqui. Chrome bajo OSX.

Lo soluciono sin usar socket.removeAllListeners(); sino socket.off("whatever") para todos mis oyentes no técnicos además "disconnect" y así sucesivamente. Funciona bien. Los mensajes de error en la consola del navegador son molestos, pero no valen la pena para mí.

Tengo que decir que es decepcionante ver este problema sin ningún tipo de atención. Son seis meses y contando.

Entonces, el motivo de la reconexión es el tiempo de espera de ping para mí. Incluso con la degradación, sigo recibiendo el error.

¡Estoy completamente de acuerdo con una biblioteca tan grande con una base de código extensa pero sin atención a este problema!

¡Espero que alguien lo haga pronto!

Enviado desde mi iPhone

El 28 de noviembre de 2018 a las 14:14, HorseBadorties [email protected] escribió:

El mismo problema aqui. Chrome bajo OSX.

Lo soluciono sin usar socket.removeAllListeners(); pero socket.off ("lo que sea") para todos mis oyentes no técnicos además de "desconectar", etc. Funciona bien. Los mensajes de error en la consola del navegador son molestos, pero no valen la pena para mí.

Tengo que decir que es decepcionante ver este problema sin ningún tipo de atención. Son seis meses y contando.


Estás recibiendo esto porque comentaste.
Responda a este correo electrónico directamente, véalo en GitHub o silencie el hilo.

Mismo problema... me sorprende que aún no se haya solucionado esto.

Me he topado con este problema. En mi caso, la desconexión se debió a ping timeout . Sin embargo, no hubo suerte sobre por qué el lado del cliente dejó de responder a los pings.

io.on('connection', function(socket) {
  socket.on('disconnect', function(reason) {
  console.log(`Socket disconnected for: ${reason}`);
  }
});

https://socket.io/docs/server-api/#Event -%E2%80%98disconnect%E2%80%99 tiene una lista de motivos de desconexiones.

Más depuración:
image
Una observación es que el evento ping en el cliente está a +30s del último. Cada vez que vi la desconexión, fue 30s+ que es el intervalo de latido predeterminado + tiempo de espera de ping. +26s , +28s y +29s aparecieron sin una desconexión.
Al compararlo con Safari, Safari fue más consistente al hacer ping cada 25s y no vio ninguna desconexión.

Hay un cambio para el pingTimeout predeterminado de 60000 (v2.0.4) a 5000 (v2.1.0+) que no es suficiente para algunos navegadores como Chrome.

La solución a este problema en v2.1.0+, incluida la última v2.2.0, es anular el pingTimeout predeterminado en su servidor a un valor grande de la siguiente manera:

const http = require('http');
const server = http.createServer();
const io = require('socket.io')(server, {
  pingTimeout: 60000,
});

O

const io = require('socket.io')();
const http = require('http');
const server = http.createServer();
io.attach(server, {
  pingTimeout: 60000,
});

¿Por qué 5000 no es suficiente? Estoy viendo este problema en mi servidor de desarrollo local, y la latencia entre el cliente y el servidor ciertamente está por debajo de ese umbral. 5000ms parece un tiempo de espera razonable. Huele a que podría haber un problema con el sistema de ping-pong en sí, y solo se manifestó cuando se bajó.

Gracias por iniciar este hilo @getify (estoy en socket.io v2.2.0)

Para cualquier persona que también esté experimentando esto: YO TAMBIÉN LOS COMENTARIOS NO AYUDAN :-) voten el problema con un pulgar para mostrar su apoyo 👍

Gracias @omardoma por descubrir el pingTimeout y estoy de acuerdo con @LunarMist en que debemos investigar el sistema de eventos ping/pong .

Hice algunas pruebas preliminares con Chrome, Firefox y Safari (todos en MacOS).

Chrome y Safari parecen acelerar la actividad de ws con diferentes comportamientos y restricciones:

  • Chrome, después de ~5 minutos de inactividad cuando la pestaña está enfocada o inmediatamente cuando la pestaña pasa a segundo plano. Esto es intencional por parte del equipo de cromo (https://developers.google.com/web/updates/2017/03/background_tabs)
  • Safari, casi inmediatamente cuando el foco de la aplicación cambia a otra aplicación de escritorio (MacOS) o cuando la pestaña pasa a un segundo plano. Relacionado con #2924
  • Firefox, *nunca ha mencionado ningún problema en este hilo

Soluciones

Probé durante varias horas con estos 3 navegadores, cambiando los valores pingTimeout y pingInterval . Lo que encontré para ser soluciones:

  1. Configuración pingTimeout >= 30000 ms

    • o -

  2. Configuración pingInterval <= 10000 ms

Creo que la mejor solución es cambiar pingTimeout = 30000 . El pingInterval predeterminado es 25000 ms y aumentar la frecuencia de los clientes que hacen ping al servidor cada 10 puede ser demasiado hablador para proyectos _a escala_.


¿Está @darrachequesne o cualquier otro miembro del repositorio a favor de aumentar el valor predeterminado pingTimeout a 30000 desde el valor predeterminado actual de 5000 ms que se cambió en v2.1 de 60000 ms?

Reaccionar a su propio comentario tampoco ayuda.

Los clientes son los que hacen ping al servidor y no al revés.

Creo que eso se debe a que la versión actual de socket.io se basa en setTimeout en el lado del cliente, que puede no ser tan confiable como se esperaba.

Creo que aumentar pingTimeout debería solucionar el problema temporalmente, pero usaremos ping/pong desde el servidor -> cliente (en lugar del cliente actual -> servidor) en v3.

Simplemente use el siguiente código en el extremo del cliente.

_socket.on('ping', () => {
socket.emit(datos);
});_

¡Gracias @crobinson42! La solución de tiempo de espera de ping funcionó muy bien para mí. Solo tengo algunas preocupaciones sobre esa solución. Si perdió la conexión a Internet en algún momento, el evento de desconexión tardará hasta 30 segundos en activarse y, para algunas aplicaciones, es demasiado. por ejemplo, una aplicación de chat que quiere deshabilitar la entrada de texto cuando el usuario no está conectado.

En este caso, aumentar el intervalo de ping haría el trabajo, pero como dijiste, el costo es alto, ¿hay alguna solución para esto?

Háganos saber una vez que esto se solucione, el mismo problema para mí, mis versiones son las siguientes:

"socket.io": "2.2.0",
"socket.io-adapter": "~1.1.1",
"socket.io-client": "2.2.0",
"socket.io-parser": "~3.2.0",
"socket.io-redis": "^5.2.0",

Mi código:
servidor, {
ruta: '/socket.io',
servirCliente: cierto,
// debajo están las opciones de engine.IO
Intervalo de ping: 40000,
tiempo de espera de ping: 25000,
upgradeTimeout: 30000, // el valor predeterminado es 10000ms, intente cambiarlo a 20k o más
agente: falso,
galleta: falso,
rechazoNo autorizado: falso,
reconexiónRetraso: 1000,
reconexiónDelayMax: 5000
}

mi cliente:

reconexión: cierto,
reconexiónRetraso: 1000,
reconexiónDelayMax: 5000,
intentos de reconexión: infinito,
//nuestras opciones del sitio
transportes: ["sondeo", "websocket"],
seguro: cierto,
rechazoNo autorizado: falso,
fuerzaNuevo: cierto,
tiempo de espera: 60000

Hola Faizán,
Puede hacer que este código se ejecute como -
** He usado la misma versión que usted me dio..

Lado del servidor - Código:

const servidor = require('http').createServer();
const io = require('socket.io')(servidor, {
// ruta: '/socket.io',
servirCliente: cierto,

pingInterval: 40000,
pingTimeout: 25000,
upgradeTimeout: 21000, // default value is 10000ms, try changing it to 20k or more
agent: false,
cookie: false,
rejectUnauthorized: false,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000

});

io.on('conexión', función(socket) {
socket.emit('bienvenido', { mensaje: '¡Bienvenido!', id: socket.id });
socket.on('Sunil', consola.log);
});

servidor.escucha(3000);

Código del lado del cliente:

var cliente = require("socket.io-client");
var socket = cliente.conectar("http://localhost:3000", {
reconexión: cierto,
reconexiónRetraso: 1000,
reconexiónDelayMax: 5000,
intentos de reconexión: infinito,
transportes: ["websocket"],
seguro: falso,
rechazoNo autorizado: falso,
fuerzaNuevo: cierto,
tiempo de espera: 6000
});

enchufe.conectar();
socket.emit('Sunil', {
datos: 'Hola'
});
socket.on('bienvenido', función (datos) {
consola.log(datos)
socket.emit('Sunil', {
datos: 'Faizán',
id: datos.id
});

socket.disconnect();

});

Saludos
Sunil Yadav

El 9 de mayo de 2019, a las 4:05 p. m., Faizan Zahid [email protected] escribió:

reconexión: cierto,
reconexiónRetraso: 1000,
reconexiónDelayMax: 5000,
intentos de reconexión: infinito,
//nuestras opciones del sitio
transportes: ["sondeo", "websocket"],
seguro: cierto,
rechazoNo autorizado: falso,
fuerzaNuevo: cierto,
tiempo de espera: 60000

Posiblemente una solución en el lado del cliente si alguien está interesado hasta que se solucione el problema. Esto hará que el navegador no libere memoria y puede causar un uso excesivo de la memoria.

  • Como se indica aquí, https://apple.stackexchange.com/questions/344183/safari-12-mac-does-includeinternaldebugmenu-1-still-work , primero otorgue a la aplicación Terminal acceso completo al disco localmente y reinicie la terminal.
  • Abra una ventana de terminal, pegue y ejecute el comando defaults write com.apple.Safari IncludeInternalDebugMenu 1
  • Reinicia Safari. Verá un nuevo menú Depurar en la parte superior derecha.
  • En Depuración-> Indicadores varios, habilite dos indicadores "Deshabilitar siesta de aplicación" y "Deshabilitar aceleración del temporizador de página oculta" y reinicie Safari.

Si alguien tiene una solución alternativa de Chrome, eso ayudaría

¿Usas Safari para localhost webdev? 🤔

¿Usas Safari para localhost webdev? 🤔

No realmente, pero es molesto con desconexiones constantes para probar mi aplicación. Esto proporciona una solución temporal hasta que se solucione en 3.0. Esta no es una solución. Publiqué si ayudará a alguien durante el desarrollo.

Estoy usando pingInterval y pingTimeouts muy bajos para obtener cambios de estado fuera de línea en tiempo real, establecerlo en 30 segundos interrumpiría mi flujo... ¿alguien sabe una manera de resolver este problema para poder usar la "corrección" de tiempo de espera prolongado para el navegador en segundo plano? ¿pestañas?

¿Alguna actualización sobre esto?

Estoy usando pingInterval y pingTimeouts muy bajos para obtener cambios de estado fuera de línea en tiempo real, establecerlo en 30 segundos interrumpiría mi flujo... ¿alguien sabe una manera de resolver este problema para poder usar la "corrección" de tiempo de espera prolongado para el navegador en segundo plano? ¿pestañas?

Debes desconectar los eventos en el socket para manejar la presencia, cuando el socket se desconecte, encuentra al usuario y márcalo como fuera de línea en tu almacén de datos.

Estos son los valores predeterminados de la documentación. Parece que se envía un ping cada 25 segundos y cada ping tiene 5 segundos para completarse.

tiempo de espera de ping | 5000 | cuantos ms sin un paquete pong para considerar la conexion cerrada
-- | -- | --
Intervalo de ping | 25000 | cuantos ms antes de enviar un nuevo paquete de ping

Me di cuenta de este mismo error pero en un contexto diferente, así que voy a hacer una redacción rápida con mi problema y solución para cualquier otra persona que termine aquí.

Mi escenario estaba en Chrome para Android, donde la conexión se interrumpe después de bloquear la pantalla.

Estoy usando un token para identificar al mismo usuario en diferentes conexiones, que envío desde el cliente al conectarme usando el enfoque de opción de consulta y actualizo el token con uno nuevo recibido del servidor:

// client
io('myAppUrl', {
  query: {
    token: localStorage.getItem('myKey') || ''
  }
});

io.on('reconnect_attempt', () => {
  io.opts.query = {
    token: localStorage.getItem('myKey') || ''
  };
});

io.on('my_custom_connection_successful_event', (token) => {
  localStorage.setItem('myKey', token);
});

El problema es que el cliente de Chrome para Android enviaría al servidor un token de cadena vacío al volver a conectarse. Lo cual no esperaría ya que agregué el oyente 'reconnect_attempt' que se asegura de establecer el último token de localStorage .

Bueno, después de un par de horas de depuración con la consola registrando todos los posibles eventos del cliente, me di cuenta de que el evento 'reconnect_attempt' no se activa en absoluto en mi escenario de reconexión. Después de desbloquear la pantalla, obtengo la siguiente secuencia de eventos:

  • desconectar (motivo: 'transporte cerrado')
  • reconectando (intento: 1)
  • reconectar
  • ping/pong comienza de nuevo

Por lo tanto, no se activa ningún evento 'reconnect_attempt' , lo que explica por qué el token sigue siendo una cadena vacía (el valor inicial establecido en la conexión).

Para resumir, la solución para mí es actualizar inmediatamente la variable de instancia io.opts.query en mi evento personalizado de "conexión exitosa" recibido del servidor con el nuevo token:

// client
io('myAppUrl', {
  query: {
    token: localStorage.getItem('myKey') || ''
  }
});

io.on('my_custom_connection_successful_event', (token) => {
  localStorage.setItem('myKey', token);
  io.opts.query = {
    token: token
  };
});

Ahora entiendo que io.opts.query es una variable de instancia que se usa en la conexión y en todas las reconexiones posteriores, por lo que puedo actualizarla tan pronto como lo desee. No tengo que esperar ningún evento relacionado con la reconexión.

Me siento un poco engañado por los documentos Con opciones de consulta . ¿Quizás entendí mal el caso de uso en ese ejemplo? Pero si es similar a mi caso de uso, en lugar del ejemplo de 'reconnect_attempt' los documentos podrían explicar que io.opts.query es una variable de instancia que se puede mutar y su valor actual se usa en todas las reconexiones posteriores. Por lo tanto, se puede cambiar cada vez que desee actualizar el token, incluso en un evento personalizado 'refresh_token' , por ejemplo. Puedo hacer relaciones públicas si crees que es una buena idea para mejorar los documentos.

Editar:
Luego de una mayor investigación, me di cuenta de que mi error era que el oyente 'reconnect_attempt' se estaba eliminando de otra parte de mi código... :man_facepalming: Es por eso que no lo estaba viendo en mi registro. Entonces, sí, la secuencia de eventos para mi escenario de reconexión es, de hecho:

  • desconectar (motivo: 'transporte cerrado')
  • reconnect_attempt (intento: 1)
  • reconectando (intento: 1)
  • reconectar
  • ping/pong comienza de nuevo

Aún así, mi comprensión de que io.opts.query se puede cambiar cuando lo desee sigue siendo válida. :sudor_sonrisa:

¿Todavía está bien bajar de categoría? Enciendo 2.0.3 pero parece que no funciona.

Hola, estoy enfrentando el mismo tipo de problema pero con dos errores. Probé la solución @omardoma . ¿Alguien puede ayudar?
Sistema operativo - Ubuntu 18.04
Nodo - 12.16.2
npm - 6.14.5
socket.io - 2.3.0
mi código -

aplicación.js

const speech = require('@google-cloud/speech');
const speechClient = new speech.SpeechClient(); // Creates a client
const environmentVars = require('dotenv').config();
const io = require('socket.io')();
const http = require('http');
const server = http.createServer();
io.attach(server, {
  pingTimeout: 60000,
});



console.log(io)



// =========================== SOCKET.IO ================================ //

io.on('connection', function (client) {
  console.log('Client Connected to server');
  let recognizeStream = null;

archivo ejs

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js" integrity="sha256-bQmrZe4yPnQrLTY+1gYylfNMBuGfnT/HKsCGX+9Xuqo=" crossorigin="anonymous"></script>
<script src="/js/client.js"></script>

archivo js

const socket = io.connect("http://localhost:8080");

Estoy usando socket.io versión 2.3.0. Uso una conexión websocket al cliente. Cuando mi cliente tiene una alerta del navegador (que es síncrona) en la interfaz de usuario y si el usuario no descarta la alerta durante más de 30 segundos (pingTimeout + pingInterval), veo el mensaje 'Websocket ya está en estado CERRADO o CERRADO' y obtengo un evento de desconexión con el motivo pingTimeout. No quiero que este websocket se desconecte cuando la interfaz de usuario tenga una alerta. Si aumento el pingTimeout a 10 min, la desconexión no ocurre durante 10 min. Pero por lo que leí en los comentarios anteriores, esto puede tener un impacto negativo (es posible que el cliente no sepa que hubo una desconexión hasta 10 minutos). Pero noté que si hay una interrupción de la red, etc., obtenemos una desconexión con motivo de cierre del transporte. Entonces, ¿está bien aumentar este pingTimeout+pingInterval? ¿Existe un escenario específico en el que no se detecta una desconexión? ¿O hay alguna otra forma de arreglar esto?

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