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.
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");
});
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.
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
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
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.
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:
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:
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:
pingTimeout
>= 30000
mspingInterval
<= 10000
msIch 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.
defaults write com.apple.Safari IncludeInternalDebugMenu 1
ein und führen Sie ihn ausWenn 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:
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:
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?
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:
ODER