Socket.io: Exceções JS lançadas apenas em inatividade (WebSocket já está no estado CLOSING ou CLOSED.)

Criado em 26 mai. 2018  ·  55Comentários  ·  Fonte: socketio/socket.io

Você quer:

  • [x] reportar um bug
  • [ ] solicitar um recurso

Comportamento atual

Ao deixar um soquete conectado, mas não fazendo nenhuma outra atividade em meu programa, vejo intermitentemente (mas bastante consistentemente) uma exceção lançada no console do navegador, de dentro do maquinário socket.io (especificamente na linha backo2/index.js 83. Esse erro é:

WebSocket is already in CLOSING or CLOSED state.

socket-io-errors

Etapas para reproduzir (se o comportamento atual for um bug)

Eu tenho duas guias abertas com soquetes de cliente conectados ao mesmo servidor (localhost) via https. Ambos os clientes estão ociosos, sem mais nada acontecendo no navegador ou no servidor (exceto por qualquer ping de manutenção ativo que o socket.io esteja fazendo). Ambos são unidos a um único canal (via join(..) no servidor). Caso contrário, nada mais especial.

Veja como eu crio a instância do soquete do servidor:

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

E no cliente:

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

Comportamento esperado

Espero desconexões e reconexões de tempos em tempos, mas não espero exceções espúrias de JS lançadas pela biblioteca quando não estou fazendo mais nada nas conexões.

Configuração

  • SO: Mac OSX
  • navegador: Chrome 66, nó 10.2.1
  • versão do socket.io: 2.1.1

Outras informações (por exemplo, stacktraces, problemas relacionados, sugestões de como corrigir)

Rastreamento de pilha expandido:

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

Comentários muito úteis

Há uma mudança para o pingTimeout padrão de 60000(v2.0.4) para 5000 (v2.1.0+) que não é suficiente para alguns navegadores como o Chrome.

A solução para esse problema na v2.1.0+, incluindo a v2.2.0 mais recente, é substituir o pingTimeout padrão em seu servidor para um valor grande da seguinte forma:

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

OU

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

Todos 55 comentários

Experimentando absolutamente o mesmo problema e o código está correto. Isso só acontece no Chrome para mim. Mozilla é limpo. No chrome, esse erro está chovendo repetidamente e duplicando todos os bate-papos que tenho. Eu tentei usar este método
socket.on('disconnect', () =>{ socket.disconnect(); });
Não desconecta o cliente do servidor. Repo caso seja necessário https://github.com/antoniab123456/Chat_app

o mesmo problema aqui
image

navegador está apenas inativo, então os erros aparecem.

Eu usei o Chrome e o mac OS

Sim pessoal, alguém pode resolver isso? Talvez precisemos de outra linha de código para corrigir isso?

Eu tenho o mesmo problema com socket.io e Chrome
Mac OS 10.13.5
Versão do Chrome 67.0.3396.87 (compilação oficial) (64 bits)
Nó: 10.3.0
Expresso: 4.16.3
socket.io: 2.1.1

No Firefox está tudo bem.

Detalhes do erro abaixo:

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

Quando clico no index.js:83 ele me leva para 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

A linha 83 é:

this.jitter = jitter;

Eu meio que tenho o mesmo problema, com backo2.js e na linha 83. aqui está meu erro:
index.js:83 Uncaught TypeError: Falha ao executar 'readAsArrayBuffer' em 'FileReader': o parâmetro 1 não é do tipo 'Blob'.
em n (index.js:83)
em n (index.js:83)
em n (index.js:83)
em n (index.js:83)
em n (index.js:83)
em n (index.js:83)
em Object.e.removeBlobs (index.js:83)
em s (index.js:83)
em r.encode (index.js:83)
em r.packet (index.js:83)
e não se preocupe com as outras coisas, todas estão na linha 83, que é this.jitter = jitter;
Isso está me irritando tanto que não há realmente nenhuma solução no google.

Alguém encontrou uma solução temporária? @antoniab123456 você conseguiu corrigir seu aplicativo de bate-papo para que ele não duplique seus bate-papos? Está fazendo a mesma coisa comigo.

Configuração
SO: Mac OSX
Navegador: Chrome 67.0.3396.99 (Build oficial) (64 bits)
Nó v10.5.0
Socket.io v2.1.1

Estou enfrentando o problema exato @getify mencionado no chrome. Alguém encontrou alguma solução para isso?

Mesmo problema. Alguém por favor pode responder a isso?

Mesmo problema.

Configuração
SO: Mac OSX
navegador: Chrome 67.0.3396.99 (Build oficial) (64 bits), Node 9.6.1
versão do socket.io: 2.1.1

@ 19smitgr idk o que você quer dizer com 'bate-papos duplicados', o que parece fora do tópico que pode ser resolvido por transmissão, se você quer dizer 'mensagem duplicada na mesma tela'.

@kino2007 Não estou fazendo um aplicativo de bate-papo. Na verdade, estou usando websockets com um jogo multiplayer, e o websocket não estava recebendo uma mensagem de desconexão, então quando o usuário desconectava e reconectava devido ao erro aleatório que todos estão falando, ele dava ao personagem um novo ID de soquete, e o sprite antigo com o ID do soquete antigo não foi excluído porque estava apenas recebendo uma mensagem de "transporte fechado" em vez de uma mensagem de "desconexão".

Neste ponto, mesmo se eu receber uma mensagem de "transporte fechado", simplesmente excluo o usuário da minha lista de usuários atuais da mesma forma como se eu recebesse uma mensagem de "desconexão".

Mesmo erro aqui

Após uma pesquisa rápida, descobri que o backo2 causa o erro.

Então eu usei a versão dev do socket.io e descobri que o Socket.prototype.onevent lança o erro.

Eu consertei para mim:

Anteriormente eu usava isso:

socket.on('ping', alert);

Mas depois mudei para isso:

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

E funcionou!

Estou tendo o mesmo problema. Alguma atualização sobre isso?

Mesmo aqui.

socket.io & socket.io-client: "^2.1.1"
Mac OS
Google Chrome está atualizado
Versão 68.0.3440.106 (compilação oficial) (64 bits)

Estou tendo o mesmo problema. Além disso, está duplicando as mensagens que envio do servidor para o cliente.

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

Mac OS: 10.13.6
Socket.io: "^2.1.1"
Chrome: 68.0.3440.106

@abhyuditjain Você pode tentar redefinir todos os ouvintes usando socket.removeAllListeners(); para evitar vários registros de ouvintes que podem causar mensagens duplicadas.

Este parece ser um problema contínuo para várias pessoas e não houve nenhuma solução para isso. Alguma atualização de alguém?

@vkotu Se eu remover todos os ouvintes, o soquete não se reconectará ao servidor na desconexão. Algum jeito de arrumar isso?

basta usar o websocket-node, é fácil de usar e funciona sem erros e além disso você não precisa de uma biblioteca externa para isso:
https://codeburst.io/why-you-don-t-need-socket-io-6848f1c871cd
https://medium.com/@martin.sikora/node -js-websocket-simple-chat-tutorial-2def3a841b61
https://www.npmjs.com/package/websocket

não um anúncio, apenas ajudando, a menos que você tenha uma decisão para este erro :DDD está acontecendo há meses05.09.2018, 13:15, "Abhyudit Jain" [email protected] :@antoniab123456 Esta página é para postar problemas sobre isso repositório. Por favor, não anuncie aqui.

—Você está recebendo isso porque foi mencionado.Responda a este e-mail diretamente, visualize-o no GitHub ou silencie o tópico.

-- Atenciosamente, Antonia B. Especialista em Atendimento ao Cliente @amoCRM Global

Fazer o downgrade para 2.0.3 "corrigiu" esse problema para mim.

@cozuya vai testar. Avisarei se funcionou!

Fazer o downgrade para 2.0.3 "corrigiu" esse problema para mim.

parece estar fazendo o truque. Testado por 4 minutos e sem erros. Vamos ver quanto tempo dura!

@cozuya obrigado por postar isso!

Mesmo erro em 2.1.1

Fazer o downgrade para 2.0.3 "corrigiu" esse problema para mim.

2.0.3 funciona para mim! Obrigado @cozuya

2.1.1 ainda enfrentando os mesmos problemas. Tentei aumentar o ping e o tempo limite, mas nada mudou

tendo o mesmo problema no chrome com v2.1.1, enquanto o navegador está inativo por um longo tempo (cerca de 20-30 minutos)

2.1.1 ainda enfrentando os mesmos problemas. Tentei aumentar o ping e o tempo limite, mas nada mudou

downgrade para v 2.0.3

Eu tentei usar socket.io com 2.0.4, parece normal.

Descobri que há uma mudança para o pingTimeout de 60000 (v2.0.4) para 5000 (v2.1.1)

Se eu alterei pingTimeout para um número maior, como 10000s, parece funcionar.

Eu acho que pode estar relacionado ao navegador ocioso, onde a guia inativa terá algum acelerador.

Tive algum problema. Alguém resolveu o problema?

Tive que baixar também. Não estava funcionando para chrome e safari

Mesmo problema aqui. Chrome sob OSX.

Eu resolvo isso não usando socket.removeAllListeners(); mas socket.off("whatever") para todos os meus ouvintes não técnicos além "disconnect" e assim por diante. Funciona bem. As mensagens de erro no console do navegador são irritantes, mas não valem um downgrade para mim.

Devo dizer que é decepcionante ver esse problema sem qualquer atenção. São seis meses e contando.

Portanto, o motivo da reconexão é o tempo limite de ping para mim. Mesmo com o downgrade, ainda estou recebendo o erro.

Concordo completamente com uma biblioteca tão grande com extensa base de código, mas sem atenção a esse problema!

Espero que alguém consiga logo!

Enviado do meu iPhone

Em 28 de novembro de 2018, às 14h14, HorseBadorties [email protected] escreveu:

Mesmo problema aqui. Chrome sob OSX.

Eu resolvo isso não usando socket.removeAllListeners(); mas socket.off("whatever") para todos os meus ouvintes não técnicos além de "disconnect" e assim por diante. Funciona bem. As mensagens de erro no console do navegador são irritantes, mas não valem um downgrade para mim.

Devo dizer que é decepcionante ver esse problema sem qualquer atenção. São seis meses e contando.


Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub ou silencie a conversa.

Mesmo problema .... surpreso, nenhuma correção foi feita para isso ainda.

Eu ter deparado com este problema. No meu caso, a desconexão foi devido a ping timeout . No entanto, nenhuma sorte sobre por que o lado do cliente parou de responder aos 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 tem uma lista de motivos para desconexões.

Mais depuração:
image
Uma observação é que o evento ping no cliente é +30s do último. Cada vez que eu via a desconexão, era 30s+ que é o intervalo de pulsação padrão + tempo limite de ping. +26s , +28s e +29s apareceram sem desconexão.
Ao comparar com o Safari, o Safari foi mais consistente no ping a cada 25s e não viu nenhuma desconexão.

Há uma mudança para o pingTimeout padrão de 60000(v2.0.4) para 5000 (v2.1.0+) que não é suficiente para alguns navegadores como o Chrome.

A solução para esse problema na v2.1.0+, incluindo a v2.2.0 mais recente, é substituir o pingTimeout padrão em seu servidor para um valor grande da seguinte forma:

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

OU

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

Por que 5000 não é suficiente? Estou vendo esse problema no meu servidor de desenvolvimento local e a latência entre o cliente e o servidor certamente está abaixo desse limite. 5000ms parece um tempo limite razoável. Parece que pode haver um problema com o próprio sistema de pingue-pongue, e só se manifestou quando foi abaixado.

Thx por iniciar este tópico @getify (estou no socket.io v2.2.0)

Para qualquer pessoa que também esteja passando por isso - COMENTÁRIOS EU TAMBÉM NÃO AJUDAM :-) vote no problema com um polegar para mostrar seu apoio 👍

Obrigado @omardoma por descobrir o pingTimeout e eu concordo com @LunarMist que devemos investigar o sistema de eventos ping/pong .

Fiz alguns testes preliminares com Chrome, Firefox e Safari (todos no MacOS).

O Chrome e o Safari parecem limitar a atividade do ws com diferentes comportamentos e restrições:

  • Chrome, após cerca de 5 minutos de inatividade quando a guia está focada ou imediatamente quando a guia fica em segundo plano. Isso é intencional pela equipe do chromium (https://developers.google.com/web/updates/2017/03/background_tabs)
  • Safari, quase imediatamente quando o foco do aplicativo é alterado para outro aplicativo de desktop (MacOS) ou quando a guia fica em segundo plano. Relacionado a #2924
  • Firefox, * nunca teve problemas mencionados neste tópico

Soluções

Testei por várias horas com todos esses 3 navegadores, alterando os valores pingTimeout & pingInterval . O que achei soluções:

  1. Configurando pingTimeout >= 30000 ms

    • ou -

  2. Configurando pingInterval <= 10000 ms

Acredito que a melhor solução seja mudar pingTimeout = 30000 . O padrão pingInterval é 25000 ms e aumentar a frequência dos clientes que fazem ping no servidor a cada 10s pode ser muito chato para projetos _at scale_.


O @darrachequesne ou qualquer outro membro do repo é a favor de aumentar o padrão pingTimeout para 30000 do padrão atual de 5000 ms que foi alterado na v2.1 de 60000 ms?

Reagir ao seu próprio comentário também não ajuda.

Os clientes são os que fazem ping no servidor e não o contrário.

Acho que é porque a versão atual do socket.io depende do setTimeout no lado do cliente, que pode não ser tão confiável quanto o esperado.

Acho que aumentar o pingTimeout deve corrigir temporariamente o problema, mas usaremos ping/pong do servidor -> cliente (em vez do cliente atual -> servidor) na v3.

Basta usar o seguinte código no cliente final.

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

Obrigado @crobinson42! A solução de tempo limite de ping funcionou muito bem para mim. Estou apenas tendo algumas preocupações sobre essa solução. Se você perdeu a conexão com a Internet a qualquer momento, levará até 30 segundos para que o evento de desconexão seja acionado e, para alguns aplicativos, isso é demais. por exemplo, um aplicativo de bate-papo que deseja desabilitar a entrada de texto quando o usuário não está conectado.

Nesse caso, aumentar o intervalo de ping faria o trabalho, mas como você disse, o custo é alto, existe alguma solução alternativa para isso?

Por favor, avise-nos assim que isso for corrigido, mesmo problema para mim, minhas versões r abaixo:

"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",

Meu código:
servidor, {
caminho: '/socket.io',
serveCliente: true,
// abaixo estão as opções do engine.IO
pingIntervalo: 40000,
pingTimeout: 25000,
upgradeTimeout: 30000, // valor padrão é 10000ms, tente mudar para 20k ou mais
agente: falso,
biscoito: falso,
rejeitarNão autorizado: falso,
Atraso de reconexão: 1000,
ReconnectionDelayMax: 5000
}

meu cliente:

reconexão: verdade,
Atraso de reconexão: 1000,
ReconnectionDelayMax: 5000,
Tentativas de reconexão: Infinito,
// nossas opções de site
transports: ["polling", "websocket"],
seguro: verdadeiro,
rejeitarNão autorizado: falso,
forceNew: true,
tempo limite: 60000

Olá Faizan,
Você pode ter este código em execução como -
** Eu usei a mesma versão dada por você.

Lado do Servidor - Código :

const server = require('http').createServer();
const io = require('socket.io')(servidor, {
// caminho: '/socket.io',
serveCliente: true,

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('conexão', function(socket) {
socket.emit('welcome', { message: 'Welcome!', id: socket.id });
socket.on('Sunil', console.log);
});

server.listen(3000);

Código do lado do cliente:

var cliente = require("socket.io-client");
var socket = client.connect("http://localhost:3000", {
reconexão: verdade,
Atraso de reconexão: 1000,
ReconnectionDelayMax: 5000,
Tentativas de reconexão: Infinito,
transporta: ["websocket"],
seguro: falso,
rejeitarNão autorizado: falso,
forceNew: true,
tempo limite: 6000
});

socket.connect();
socket.emit('Sunil', {
dados: 'Olá'
});
socket.on('bem vindo', function (dados) {
console.log(dados)
socket.emit('Sunil', {
dados: 'Faizan',
id: data.id
});

socket.disconnect();

});

Cumprimentos
Sunil Yadav

Em 09 de maio de 2019, às 16h05, Faizan Zahid [email protected] escreveu:

reconexão: verdade,
Atraso de reconexão: 1000,
ReconnectionDelayMax: 5000,
Tentativas de reconexão: Infinito,
// nossas opções de site
transports: ["polling", "websocket"],
seguro: verdadeiro,
rejeitarNão autorizado: falso,
forceNew: true,
tempo limite: 60000

Possivelmente uma solução alternativa no lado do cliente, se alguém estiver interessado até que o problema seja corrigido. Isso fará com que o navegador não libere memória e pode causar uso excessivo de memória.

  • Conforme listado aqui, https://apple.stackexchange.com/questions/344183/safari-12-mac-does-includeinternaldebugmenu-1-still-work , primeiro conceda acesso total ao disco do aplicativo Terminal localmente e reinicie o terminal.
  • Abra uma janela de terminal e cole e execute o comando defaults write com.apple.Safari IncludeInternalDebugMenu 1
  • Reinicie o Safari. Você verá um novo menu Debug no canto superior direito.
  • Em Debug->Miscellaneous Flags, habilite dois sinalizadores “Disable App Nap” e “Disable Hidden Page Timer Throttling” e reinicie o Safari.

Se alguém tiver uma solução alternativa do Chrome, isso ajudaria

Você usa o Safari para webdev localhost? 🤔

Você usa o Safari para webdev localhost? 🤔

Não realmente, mas é irritante com desconexões constantes para testar meu aplicativo. Isso fornece uma solução temporária até que seja corrigido na versão 3.0. Esta não é uma solução. Eu postei se isso vai ajudar alguém durante o desenvolvimento.

Estou usando muito baixo pingInterval e pingTimeouts para obter alterações de status offline em tempo real, configurá-lo para 30 segundos interromperia meu fluxo ... abas?

Alguma atualização sobre isso?

Estou usando muito baixo pingInterval e pingTimeouts para obter alterações de status offline em tempo real, configurá-lo para 30 segundos interromperia meu fluxo ... abas?

Você deve se os eventos de desconexão no soquete manipularem a presença, quando o soquete se desconectar, encontre o usuário e marque-o como offline em seu armazenamento de dados

Aqui estão os padrões da documentação. Parece que um ping é enviado a cada 25 segundos e cada ping tem 5 segundos para ser concluído.

pingTimeout | 5000 | quantos ms sem pacote pong para considerar a conexão fechada
-- | -- | --
pingInterval | 25000 | quantos ms antes de enviar um novo pacote de ping

Percebi esse mesmo erro, mas em um contexto diferente, então vou fazer uma rápida descrição do meu problema e solução para qualquer outra pessoa que esteja aqui.

Meu cenário foi no Chrome para Android, onde a conexão é interrompida após bloquear a tela.

Estou usando um token para identificar o mesmo usuário em diferentes conexões, que envio do cliente na conexão usando a abordagem de opção de consulta e atualizo o token com um novo recebido do 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);
});

O problema é que o cliente Chrome para Android enviaria ao servidor um token de string vazio na reconexão. O que eu não esperaria, pois adicionei o ouvinte 'reconnect_attempt' que garante definir o token mais recente de localStorage .

Bem, depois de algumas horas de depuração com o console registrando todos os possíveis eventos do cliente, percebi que o evento 'reconnect_attempt' não é disparado no meu cenário de reconexão. Após desbloquear a tela, recebo a seguinte sequência de eventos:

  • desconectar (motivo: 'transporte fechado')
  • reconectando (tentativa: 1)
  • reconectar
  • ping/pong começa novamente

Portanto, nenhum evento 'reconnect_attempt' está sendo disparado, o que explica por que o token ainda é uma string vazia (o valor inicial definido na conexão).

Para encurtar a história, a solução para mim é atualizar imediatamente a variável de instância io.opts.query no meu evento personalizado "conexão bem-sucedida" recebido do servidor com o novo 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
  };
});

Agora eu entendo que io.opts.query é uma variável de instância que é usada na conexão e em todas as reconexão subsequentes, para que eu possa atualizá-la assim que quiser. Não preciso esperar por nenhum evento relacionado à reconexão.

Eu me sinto um pouco enganado pelos documentos com opções de consulta . Talvez eu tenha entendido mal o caso de uso nesse exemplo? Mas se for semelhante ao meu caso de uso, em vez do exemplo 'reconnect_attempt' os documentos podem explicar que io.opts.query é uma variável de instância que pode ser alterada e seu valor atual é usado em todas as reconexões subsequentes. Portanto, ele pode ser alterado sempre que você quiser atualizar o token, mesmo em um evento personalizado 'refresh_token' , por exemplo. Posso fazer um PR se você achar que é uma boa ideia para melhorar os documentos.

Editar:
Após uma investigação mais aprofundada, percebi que meu erro foi que o ouvinte 'reconnect_attempt' estava sendo removido de outra parte do meu código... :man_facepalming: É por isso que não estava vendo no meu log. Então, sim, a sequência de eventos para o meu cenário de reconexão é de fato:

  • desconectar (motivo: 'transporte fechado')
  • reconnect_attempt (tentativa: 1)
  • reconectando (tentativa: 1)
  • reconectar
  • ping/pong começa novamente

Ainda assim, minha percepção de que io.opts.query pode ser alterada sempre que você quiser ainda é válida. :sweat_smile:

Ainda dá para fazer downgrade? Eu ligo 2.0.3, mas não parece funcionar.

Olá, estou enfrentando o mesmo tipo de problema, mas com dois erros. Eu tentei a solução @omardoma . Alguém pode ajudar?
OS - Ubuntu 18.04
Nó - 12.16.2
npm - 6.14.5
socket.io - 2.3.0
meu código -

app.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;

arquivo 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>

arquivo js

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

Estou usando o socket.io versão 2.3.0. Eu uso uma conexão websocket para o cliente. Quando meu cliente tem um alerta de navegador (que é síncrono) na interface do usuário e se o usuário não dispensar o alerta por mais de 30 segundos (pingTimeout + pingInterval), vejo a mensagem 'Websocket já está no estado CLOSING ou CLOSED' e recebo uma evento de desconexão com motivo pingTimeout. Não quero que este websocket se desconecte quando a interface do usuário tiver um alerta. Se eu aumentar o pingTimeout para 10 min, a desconexão não acontece por 10 min. Mas pelo que li nos comentários acima, isso pode ter um impacto negativo (o cliente pode não saber que houve uma desconexão até 10min). Mas notei que se houver uma interrupção na rede etc., obtemos uma desconexão com o motivo do fechamento do transporte. Então, tudo bem aumentar esse pingTimeout+pingInterval? Existe um cenário específico quando uma desconexão não é detectada? Ou existe alguma outra maneira de corrigir isso?

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

shashuec picture shashuec  ·  4Comentários

chfeizy picture chfeizy  ·  3Comentários

karmac2015 picture karmac2015  ·  3Comentários

Elliot9 picture Elliot9  ·  4Comentários

varHarrie picture varHarrie  ·  3Comentários