Socket.io: JS-Ausnahmen werden nur im Leerlauf ausgelöst (WebSocket befindet sich bereits im CLOSING- oder CLOSED-Zustand.)

Erstellt am 26. Mai 2018  ·  55Kommentare  ·  Quelle: socketio/socket.io

Sie wollen:

  • [x] Fehler melden
  • [ ] eine Funktion anfordern

Aktuelles Verhalten

Während ich einen Socket verbunden lasse, aber keine andere Aktivität in meinem Programm ausführe, sehe ich zeitweise (aber ziemlich konsistent) eine Ausnahme, die in der Browserkonsole aus dem Inneren der socket.io-Maschinerie ausgelöst wird (insbesondere in backo2/index.js Zeile 83. Dieser Fehler ist:

WebSocket is already in CLOSING or CLOSED state.

socket-io-errors

Schritte zum Reproduzieren (wenn das aktuelle Verhalten ein Fehler ist)

Ich habe zwei Registerkarten geöffnet, in denen Client-Sockets über https mit demselben Server (localhost) verbunden sind. Beide Clients sitzen im Leerlauf, und nichts anderes passiert im Browser oder Server (außer dem, was Keep-Alive-Pings socket.io tut). Beide sind mit einem einzigen Kanal verbunden (über join(..) auf dem Server). Sonst nichts Besonderes.

So erstelle ich die Server-Socket-Instanz:

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

Und im Client:

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

Erwartetes Verhalten

Ich erwarte von Zeit zu Zeit Trennungen und Wiederverbindungen, aber ich erwarte keine falschen JS-Ausnahmen, die von der Bibliothek ausgelöst werden, wenn ich nichts anderes über die Verbindungen mache.

Aufstellen

  • Betriebssystem: Mac OSX
  • Browser: Chrome 66, Knoten 10.2.1
  • socket.io-Version: 2.1.1

Sonstige Informationen (z. B. Stacktraces, verwandte Probleme, Lösungsvorschläge)

Erweiterter Stack-Trace:

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

Hilfreichster Kommentar

Es gibt eine Änderung für das Standard-PingTimeout von 60000 (v2.0.4) auf 5000 (v2.1.0+), was für einige Browser wie Chrome nicht ausreicht.

Die Lösung für dieses Problem auf Version 2.1.0+ einschließlich der neuesten Version 2.2.0 besteht darin, den standardmäßigen pingTimeout auf Ihrem Server wie folgt auf einen großen Wert zu überschreiben:

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

ODER

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

Alle 55 Kommentare

Habe absolut das gleiche Problem und der Code ist korrekt. Bei mir passiert das nur in Chrome. Mozilla ist sauber. In Chrome regnet dieser Fehler immer und immer wieder und dupliziert alle Chats, die ich habe. Ich habe es mit dieser Methode versucht
socket.on('disconnect', () =>{ socket.disconnect(); });
Es trennt den Client nicht vom Server. Repo falls erforderlich https://github.com/antoniab123456/Chat_app

hier das gleiche Problem
image

Browser ist nur im Leerlauf, dann kommen die Fehler.

Ich habe Chrome und Mac OS verwendet

Ja Leute, kann das jemand ansprechen? Vielleicht brauchen wir eine weitere Codezeile, um das zu beheben?

Ich habe das gleiche Problem mit socket.io und Chrome
Mac OS 10.13.5
Chrome-Version 67.0.3396.87 (offizieller Build) (64-Bit)
Knoten: 10.3.0
Express: 4.16.3
socket.io: 2.1.1

Bei Firefox ist alles in Ordnung.

Fehlerdetails unten:

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

Wenn ich auf index.js:83 klicke, komme ich zu diesem Modul:

/**
 * 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

Zeile 83 lautet:

this.jitter = jitter;

Ich habe irgendwie das gleiche Problem, mit backo2.js und in Zeile 83. Hier ist mein Fehler:
index.js:83 Uncaught TypeError: „readAsArrayBuffer“ konnte nicht auf „FileReader“ ausgeführt werden: Parameter 1 ist nicht vom Typ „Blob“.
bei n (index.js:83)
bei n (index.js:83)
bei n (index.js:83)
bei n (index.js:83)
bei n (index.js:83)
bei n (index.js:83)
bei Object.e.removeBlobs (index.js:83)
bei s (index.js:83)
bei r.encode (index.js:83)
bei r.packet (index.js:83)
und mach dir keine Gedanken über die anderen Sachen, sie sind alle in Zeile 83, was this.jitter = jitter; ist
Es nervt mich so sehr, da es in Google nicht wirklich eine Lösung gibt.

Hat jemand eine Übergangslösung gefunden? @antoniab123456 konntest du deine Chat-App so reparieren, dass sie deine Chats nicht dupliziert? Bei mir macht es das gleiche.

Aufstellen
Betriebssystem: Mac OSX
Browser: Chrome 67.0.3396.99 (offizieller Build) (64-Bit)
Knoten v10.5.0
Socket.io v2.1.1

Ich stehe vor genau dem Problem, das @getify in Chrome erwähnt. Hat jemand eine Lösung dafür gefunden?

Gleiches Problem. Kann bitte jemand darauf antworten?

Gleiches Problem.

Aufstellen
Betriebssystem: Mac OSX
Browser: Chrome 67.0.3396.99 (Offizieller Build) (64-Bit), Node 9.6.1
socket.io-Version: 2.1.1

@ 19smitgr idk, was Sie mit "doppelten Chats" meinen, was nicht zum Thema gehört und stattdessen durch Senden gelöst werden könnte, wenn Sie "doppelte Nachricht auf demselben Bildschirm" meinen.

@kino2007 Ich mache keine Chat-Anwendung. Ich verwende Websockets tatsächlich mit einem Multiplayer-Spiel, und das Websocket erhielt keine Meldung zum Trennen. Wenn der Benutzer also aufgrund des zufälligen Fehlers, über den alle sprechen, die Verbindung getrennt und wieder hergestellt hat, hat dies dem Charakter eine neue Socket-ID gegeben. und das alte Sprite mit der alten Socket-ID wurde nicht gelöscht, weil es nur eine "Transport Close"-Meldung statt einer "Disconnect"-Meldung erhielt.

An diesem Punkt lösche ich den Benutzer, selbst wenn ich eine „Transport close“-Nachricht erhalte, einfach aus meiner Liste der aktuellen Benutzer, genauso wie wenn ich eine „Disconnect“-Nachricht erhalten würde.

Hier der gleiche Fehler

Nach einer kurzen Suche fand ich heraus, dass backo2 den Fehler verursacht.

Dann habe ich die dev-Version von socket.io verwendet und herausgefunden, dass das Socket.prototype.onevent den Fehler auslöst.

Ich habe es für mich behoben:

Früher habe ich das verwendet:

socket.on('ping', alert);

Aber dann habe ich es so geändert:

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

Und es hat funktioniert!

Ich habe das gleiche Problem. Irgendwelche Updates dazu?

Hier gilt das gleiche.

socket.io & socket.io-client: "^2.1.1"
Mac OS
Google Chrome ist aktuell
Version 68.0.3440.106 (offizieller Build) (64-Bit)

Ich habe das gleiche Problem. Außerdem werden Nachrichten dupliziert, die ich vom Server zum Client sende.

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

MacOS: 10.13.6
Socket.io: "^2.1.1"
Chrom: 68.0.3440.106

@abhyuditjain Sie können versuchen, alle Listener mit socket.removeAllListeners(); zurückzusetzen, um mehrere Listener-Registrierungen zu vermeiden, die zu doppelten Nachrichten führen könnten.

Dies scheint ein anhaltendes Problem für mehrere Menschen zu sein, und es gab keine Lösung dafür. Irgendwelche Updates von jemandem?

@vkotu Wenn ich alle Listener entferne, verbindet sich der Socket beim Trennen nicht wieder mit dem Server. Gibt es eine Möglichkeit, dies zu beheben?

Verwenden Sie einfach websocket-node, es ist einfach zu bedienen und funktioniert ohne Fehler und außerdem benötigen Sie dafür keine externe Bibliothek:
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

keine Werbung, nur Hilfe, es sei denn, Sie haben eine Entscheidung für diesen Fehler :DDD es geht seit Monaten so 05.09.2018, 13:15, "Abhyudit Jain" [email protected] :@antoniab123456 Diese Seite ist zum Posten von Problemen dazu Repository. Bitte keine Werbung hier drüben.

– Sie erhalten dies, weil Sie erwähnt wurden. Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder schalten Sie den Thread stumm.

-- Mit freundlichen Grüßen, Antonia B. Kundendienstspezialistin @amoCRM Global

Ein Downgrade auf 2.0.3 hat dieses Problem für mich "behoben".

@cozuya wird es testen. Werde berichten ob es geklappt hat!

Ein Downgrade auf 2.0.3 hat dieses Problem für mich "behoben".

scheint den Trick zu tun. 4 Minuten getestet und keine Fehler. Mal sehen wie lange es hält!

@cozuya Danke für das Posten!

Gleicher Fehler in 2.1.1

Ein Downgrade auf 2.0.3 "behob" dieses Problem für mich.

2.0.3 funktioniert bei mir! Danke @cozuya

2.1.1 steht immer noch vor den gleichen Problemen. Versucht, Ping und Timeout zu erhöhen, aber nichts hat sich geändert

das gleiche Problem in Chrome mit v2.1.1, während der Browser lange Zeit im Leerlauf ist (ca. 20-30 Minuten)

2.1.1 steht immer noch vor den gleichen Problemen. Versucht, Ping und Timeout zu erhöhen, aber nichts hat sich geändert

Downgrade auf Version 2.0.3

Ich habe versucht, socket.io mit 2.0.4 zu verwenden, es sieht normal aus.

Ich habe festgestellt, dass es eine Änderung für das PingTimeout von 60000 (v2.0.4) auf 5000 (v2.1.1) gibt.

Wenn ich pingTimeout auf eine größere Zahl wie 10000s geändert habe, scheint es zu funktionieren.

Ich denke, es kann sich auf den Leerlauf des Browsers beziehen, bei dem inaktive Registerkarten etwas Gas geben.

Ich hatte ein Problem. Hat jemand das Problem gelöst?

Ich musste auch downgraden. Es funktionierte nicht für Chrome und Safari

Selbes Problem hier. Chrome unter OSX.

Ich arbeite darum, indem ich nicht socket.removeAllListeners(); , sondern socket.off("whatever") für alle meine nicht-technischen Zuhörer außer "disconnect" und so weiter verwende. Funktioniert gut. Die Fehlermeldungen in der Browser-Konsole sind zwar nervig, aber für mich kein Downgrade wert.

Ich muss sagen, es ist enttäuschend, dieses Problem ohne jegliche Aufmerksamkeit zu sehen. Es ist sechs Monate und zählt.

Der Grund für die Wiederverbindung ist also bei mir die Ping-Zeitüberschreitung. Trotz Downgrade bekomme ich den Fehler immer noch.

Ich stimme einer so riesigen Bibliothek mit umfangreicher Codebasis voll und ganz zu, habe diesem Problem jedoch keine Aufmerksamkeit geschenkt!

Hoffe es kommt bald jemand dazu!

von meinem Iphone gesendet

Am 28. November 2018 um 14:14 Uhr schrieb HorseBadorties [email protected] :

Selbes Problem hier. Chrome unter OSX.

Ich umgehe es, ohne socket.removeAllListeners(); aber socket.off ("whatever") für alle meine nicht-technischen Zuhörer außer "disconnect" und so weiter. Funktioniert gut. Die Fehlermeldungen in der Browser-Konsole sind zwar nervig, aber für mich kein Downgrade wert.

Ich muss sagen, es ist enttäuschend, dieses Problem ohne jegliche Aufmerksamkeit zu sehen. Es ist sechs Monate und zählt.


Sie erhalten dies, weil Sie kommentiert haben.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder schalten Sie den Thread stumm.

Dasselbe Problem .... überrascht, dass dafür noch keine Lösung gefunden wurde.

Ich muss auf dieses Problem gestoßen sein. In meinem Fall war die Trennung auf ping timeout zurückzuführen. Kein Glück, warum die Clientseite nicht mehr auf Pings reagiert.

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 enthält eine Liste mit Gründen für Verbindungsunterbrechungen.

Mehr Debugging:
image
Eine Beobachtung ist, dass das Ereignis ping auf dem Client +30s vom letzten entfernt ist. Jedes Mal, wenn ich die Trennung sah, war es 30s+ , was das Standard-Heartbeat-Intervall + Ping-Timeout ist. +26s , +28s und +29s wurden ohne Verbindungsabbruch angezeigt.
Beim Vergleich mit Safari pingte Safari konsequenter alle 25s und sah keine Verbindungsabbrüche.

Es gibt eine Änderung für das Standard-PingTimeout von 60000 (v2.0.4) auf 5000 (v2.1.0+), was für einige Browser wie Chrome nicht ausreicht.

Die Lösung für dieses Problem auf Version 2.1.0+ einschließlich der neuesten Version 2.2.0 besteht darin, den standardmäßigen pingTimeout auf Ihrem Server wie folgt auf einen großen Wert zu überschreiben:

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

ODER

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

Warum reichen 5000 nicht aus? Ich sehe dieses Problem auf meinem lokalen Entwicklungsserver, und die Latenz zwischen Client und Server liegt mit Sicherheit unter diesem Schwellenwert. 5000 ms scheinen ein angemessenes Timeout zu sein. Es riecht, als könnte ein Problem mit dem Ping-Pong-System selbst vorliegen, und es manifestierte sich nur, als es abgesenkt wurde.

Vielen Dank für den Start dieses Threads @getify (ich bin auf socket.io v2.2.0)

An alle, die dies ebenfalls erleben - MIR AUCH KOMMENTARE HELFEN NICHT :-) Bitte stimmen Sie das Problem mit einem Daumen ab, um Ihre Unterstützung zu zeigen 👍

Danke @omardoma für die Entdeckung des pingTimeout und ich stimme @LunarMist zu, dass wir das ping/pong Ereignissystem untersuchen sollten.

Ich habe einige vorläufige Tests mit Chrome, Firefox und Safari (alle unter MacOS) durchgeführt.

Chrome und Safari scheinen beide die ws-Aktivität mit unterschiedlichem Verhalten und Einschränkungen zu drosseln:

  • Chrome, nach ca. 5 Minuten Inaktivität, wenn der Tab fokussiert ist, oder sofort, wenn der Tab in den Hintergrund wechselt. Dies ist beabsichtigt vom Chromium-Team (https://developers.google.com/web/updates/2017/03/background_tabs)
  • Safari, fast sofort, wenn der App-Fokus auf eine andere Desktop-App (MacOS) geändert wird oder wenn die Registerkarte in den Hintergrund wechselt. Verwandt mit #2924
  • Firefox, * hat nie irgendwelche Probleme, die in diesem Thread erwähnt werden

Lösungen

Ich habe mehrere Stunden lang mit allen 3 dieser Browser getestet und dabei die Werte pingTimeout und pingInterval geändert. Was ich als Lösungen gefunden habe:

  1. Einstellung pingTimeout >= 30000 ms

    • oder -

  2. Einstellung pingInterval <= 10000 ms

Ich glaube, die beste Lösung besteht darin, pingTimeout = 30000 zu ändern. Der Standardwert pingInterval ist 25000 ms, und eine Erhöhung der Häufigkeit, mit der die Clients den Server auf alle 10 Sekunden anpingen, kann für _groß angelegte_ Projekte zu geschwätzig sein.


Sind @darrachequesne oder andere Repo-Mitglieder dafür, die Standardeinstellung pingTimeout auf 30000 von der aktuellen Standardeinstellung von 5000 ms zu erhöhen, die in v2.1 von 60000 geändert wurde

Auf den eigenen Kommentar zu reagieren hilft auch nicht.

Die Clients pingen den Server an und nicht umgekehrt.

Ich denke, das liegt daran, dass die aktuelle Version von socket.io auf der Clientseite auf setTimeout angewiesen ist, was möglicherweise nicht so zuverlässig ist wie erwartet.

Ich denke, das Erhöhen von pingTimeout sollte das Problem vorübergehend beheben, aber wir werden Ping/Pong vom Server -> Client (anstelle des aktuellen Client -> Server) in v3 verwenden.

Verwenden Sie einfach den folgenden Code auf der Client-Seite.

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

Danke @crobinson42! Die Ping-Timeout-Lösung hat bei mir hervorragend funktioniert. Ich habe nur Bedenken wegen dieser Lösung. Wenn Sie die Internetverbindung zu irgendeinem Zeitpunkt verlieren, dauert es bis zu 30 Sekunden, bis das Trennereignis ausgelöst wird, und für einige Apps ist das zu viel. B. eine Chat-App, die die Texteingabe deaktivieren möchte, wenn der Benutzer nicht verbunden ist.

In diesem Fall würde eine Erhöhung des Ping-Intervalls die Arbeit erledigen, aber wie Sie sagten, sind die Kosten hoch. Gibt es dafür eine Problemumgehung?

Bitte teilen Sie uns mit, sobald dies behoben ist, dasselbe Problem für mich, meine Versionen sind unten:

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

Mein Code:
Server, {
Pfad: '/socket.io',
serveClient: wahr,
// unten sind engine.IO-Optionen
PingIntervall: 40000,
pingTimeout: 25000,
upgradeTimeout: 30000, // Standardwert ist 10000 ms, versuchen Sie es auf 20k oder mehr zu ändern
Agent: falsch,
Plätzchen: falsch,
AblehnenUnautorisiert: falsch,
Wiederverbindungsverzögerung: 1000,
WiederverbindungVerzögerungMax: 5000
}

mein Kunde:

Wiederverbindung: wahr,
Wiederverbindungsverzögerung: 1000,
WiederverbindungVerzögerungMax: 5000,
Wiederverbindungsversuche: Unendlich,
//unsere Site-Optionen
Transporte: ["polling", "websocket"],
sicher: wahr,
AblehnenUnautorisiert: falsch,
forceNew: wahr,
Zeitüberschreitung: 60000

Hallo Faizan,
Sie können diesen Code ausführen als -
** Ich habe die gleiche Version verwendet, die von Ihnen angegeben wurde.

Serverseitiger Code:

const server = require('http').createServer();
const io = require('socket.io')(server, {
// Pfad: '/socket.io',
serveClient: wahr,

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('Verbindung', Funktion(Socket) {
socket.emit('Willkommen', { Nachricht: 'Willkommen!', ID: socket.id });
socket.on('Sunil', console.log);
});

server.listen (3000);

Clientseitiger Code:

var client = require("socket.io-client");
var socket = client.connect("http://localhost:3000", {
Wiederverbindung: wahr,
Wiederverbindungsverzögerung: 1000,
WiederverbindungVerzögerungMax: 5000,
Wiederverbindungsversuche: Unendlich,
Transporte: ["Websocket"],
sicher: falsch,
AblehnenUnautorisiert: falsch,
forceNew: wahr,
Zeitüberschreitung: 6000
});

socket.connect ();
socket.emit('Sunil', {
Daten: 'Hallo'
});
socket.on('Willkommen', Funktion (Daten) {
Konsole.log (Daten)
socket.emit('Sunil', {
Daten: 'Faizan',
id: daten.id
});

socket.disconnect();

});

Grüße
Sunil Yadav

Am 09. Mai 2019 um 16:05 Uhr schrieb Faizan Zahid [email protected] :

Wiederverbindung: wahr,
Wiederverbindungsverzögerung: 1000,
WiederverbindungVerzögerungMax: 5000,
Wiederverbindungsversuche: Unendlich,
//unsere Site-Optionen
Transporte: ["polling", "websocket"],
sicher: wahr,
AblehnenUnautorisiert: falsch,
forceNew: wahr,
Zeitüberschreitung: 60000

Möglicherweise eine Problemumgehung auf Client-Seite, falls jemand interessiert ist, bis das Problem behoben ist. Dies führt dazu, dass der Browser keinen Speicher freigibt und eine übermäßige Speichernutzung verursachen kann.

  • Wie hier aufgeführt, https://apple.stackexchange.com/questions/344183/safari-12-mac-does-includeinternaldebugmenu-1-still-work , gewähren Sie der Terminal-App zunächst lokal vollen Festplattenzugriff und starten Sie das Terminal neu.
  • Öffnen Sie ein Terminalfenster, fügen Sie den Befehl defaults write com.apple.Safari IncludeInternalDebugMenu 1 ein und führen Sie ihn aus
  • Starten Sie Safari neu. Rechts oben sehen Sie ein neues Debug-Menü.
  • Aktivieren Sie unter Debug->Miscellaneous Flags die beiden Flags „Disable App Nap“ und „Disable Hidden Page Timer Throttling“ und starten Sie Safari neu.

Wenn jemand einen Chrome-Workaround hat, würde das helfen

Sie verwenden Safari für localhost webdev? 🤔

Sie verwenden Safari für localhost webdev? 🤔

Nicht wirklich, aber es nervt mit ständigen Verbindungsabbrüchen meine App zu testen. Dies bietet eine vorübergehende Problemumgehung, bis es in 3.0 behoben ist. Dies ist keine Lösung. Ich habe gepostet, ob es jemandem während der Entwicklung helfen wird.

Ich verwende sehr niedrige pingInterval und pingTimeouts, um Echtzeit-Offline-Statusänderungen zu erhalten, wenn ich es auf 30 Sekunden setze, würde mein Fluss unterbrochen werden Registerkarten?

Irgendwelche Updates dazu?

Ich verwende sehr niedrige pingInterval und pingTimeouts, um Echtzeit-Offline-Statusänderungen zu erhalten, wenn ich es auf 30 Sekunden setze, würde mein Fluss unterbrochen werden Registerkarten?

Sie sollten die Trennereignisse auf dem Socket verwenden, um die Anwesenheit zu handhaben, wenn der Socket die Verbindung trennt, den Benutzer finden und ihn in Ihrem Datenspeicher als offline markieren

Hier sind die Standardwerte aus der Dokumentation. Es sieht so aus, als würde alle 25 Sekunden ein Ping gesendet und jeder Ping hat 5 Sekunden Zeit, um abgeschlossen zu werden.

pingTimeout | 5000 | wie viele ms ohne ein Pong-Paket, um die Verbindung als geschlossen zu betrachten
-- | -- | --
PingIntervall | 25000 | wie viele ms bevor ein neues Ping-Paket gesendet wird

Ich habe denselben Fehler bemerkt, aber in einem anderen Kontext, also werde ich mein Problem und meine Lösung für alle anderen, die hier landen, schnell aufschreiben.

Mein Szenario war auf Chrome für Android, wo die Verbindung nach dem Sperren des Bildschirms getrennt wird.

Ich verwende ein Token, um denselben Benutzer über verschiedene Verbindungen hinweg zu identifizieren, das ich vom Client bei der Verbindung mit dem Abfrageoptionsansatz sende, und ich aktualisiere das Token mit einem neuen, das ich vom Server erhalten habe:

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

Das Problem besteht darin, dass der Chrome für Android-Client beim erneuten Verbinden ein leeres Zeichenfolgen-Token an den Server senden würde. Was ich nicht erwarten würde, da ich den Listener 'reconnect_attempt' hinzugefügt habe, der sicherstellt, dass das neueste Token von localStorage gesetzt wird.

Nun, nach ein paar Stunden des Debuggens mit Konsolenprotokollierung aller möglichen Client-Ereignisse wurde mir klar, dass das 'reconnect_attempt' -Ereignis in meinem Szenario der Wiederverbindung überhaupt nicht ausgelöst wird. Nach dem Entsperren des Bildschirms erhalte ich die folgende Abfolge von Ereignissen:

  • trennen (Grund: 'Transport schließen')
  • Verbindungsaufbau (Versuch: 1)
  • neu verbinden
  • Ping/Pong beginnt erneut

Es wird also kein 'reconnect_attempt' -Ereignis ausgelöst, was erklärt, warum das Token immer noch eine leere Zeichenfolge ist (der anfängliche Wert, der beim Verbinden festgelegt wurde).

Um es kurz zu machen, die Lösung für mich besteht darin, die Instanzvariable io.opts.query in meinem benutzerdefinierten Ereignis "Verbindung erfolgreich" sofort zu aktualisieren, das vom Server mit dem neuen Token empfangen wurde:

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

Jetzt verstehe ich, dass io.opts.query eine Instanzvariable ist, die beim Verbinden und allen nachfolgenden Wiederverbindungen verwendet wird, sodass ich sie aktualisieren kann, sobald ich möchte. Ich muss nicht auf ein Wiederverbindungsereignis warten.

Ich fühle mich ein wenig von den With query options -Dokumenten in die Irre geführt. Vielleicht habe ich den Anwendungsfall in diesem Beispiel falsch verstanden? Aber wenn es meinem Anwendungsfall ähnlich ist, könnte die Dokumentation anstelle des 'reconnect_attempt' -Beispiels erklären, dass io.opts.query eine Instanzvariable ist, die mutiert werden kann und deren aktueller Wert bei allen nachfolgenden Wiederverbindungen verwendet wird. Es kann also jederzeit geändert werden, wenn Sie das Token aktualisieren möchten, beispielsweise sogar bei einem benutzerdefinierten 'refresh_token' -Ereignis. Ich kann eine PR machen, wenn Sie denken, dass es eine gute Idee ist, die Dokumentation zu verbessern.

Bearbeiten:
Bei weiteren Nachforschungen wurde mir klar, dass mein Fehler darin bestand, dass der Listener 'reconnect_attempt' aus einem anderen Teil meines Codes entfernt wurde ... :man_facepalming: Deshalb habe ich ihn nicht in meiner Protokollierung gesehen. Also ja, die Ereignissequenz für mein Wiederverbindungsszenario ist tatsächlich:

  • trennen (Grund: 'Transport schließen')
  • reconnect_attempt (Versuch: 1)
  • Verbindungsaufbau (Versuch: 1)
  • neu verbinden
  • Ping/Pong beginnt erneut

Trotzdem ist meine Erkenntnis, dass io.opts.query jederzeit geändert werden kann, immer noch gültig. :sweat_smile:

Ist ein Downgrade noch ok? Ich schalte 2.0.3 ein, aber es scheint nicht zu funktionieren.

Hallo, ich stehe vor dem gleichen Problem, aber mit zwei Fehlern. Ich habe die @omardoma- Lösung ausprobiert. Kann jemand helfen?
Betriebssystem - Ubuntu 18.04
Knoten - 12.16.2
npm - 6.14.5
socket.io - 2.3.0
Mein Code -

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;

ejs-Datei

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

js-Datei

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

Ich verwende socket.io Version 2.3.0. Ich verwende eine Websocket-Verbindung zum Client. Wenn mein Client eine Browserwarnung (die synchron ist) in der Benutzeroberfläche hat und der Benutzer die Warnung nicht länger als 30 Sekunden (pingTimeout + pingInterval) schließt, sehe ich die Meldung „Websocket befindet sich bereits im CLOSING- oder CLOSED-Status“ und erhalte eine Trennereignis mit PingTimeout-Grund. Ich möchte nicht, dass dieser Websocket die Verbindung trennt, wenn die Benutzeroberfläche eine Warnung hat. Wenn ich den pingTimeout auf 10 min erhöhe, erfolgt die Trennung nicht für 10 min. Aber nach dem, was ich in den Kommentaren oben gelesen habe, kann sich dies negativ auswirken (der Kunde weiß möglicherweise erst nach 10 Minuten, dass eine Unterbrechung aufgetreten ist). Aber ich habe festgestellt, dass wir bei einer Netzwerkunterbrechung usw. eine Verbindungstrennung mit Transportschließungsgrund erhalten. Ist es also in Ordnung, dieses pingTimeout+pingInterval zu erhöhen? Gibt es ein bestimmtes Szenario, in dem eine Verbindungsunterbrechung nicht erkannt wird? Oder gibt es eine andere Möglichkeit, dies zu beheben?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen