Socket.io: Der richtige Weg für einen Client, sich wieder zu verbinden, nachdem der Server eine socket.disconnect( true ) durchgeführt hat

Erstellt am 9. März 2016  ·  35Kommentare  ·  Quelle: socketio/socket.io

Server : Knoten + socket.io

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

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

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

socket.disconnect( true );

Client : html/js + socket.io 1.4.5

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

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

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

Das obige ist vereinfacht, aber das ist die Grundlage. Die Wiederverbindung funktioniert gut, wenn ich den Client starte, wenn der Server ausgefallen ist. Der Client versucht sich mit dem Server zu verbinden und wenn ich den Server endlich starte ist die Verbindung aufgebaut.

Irgendwann kann es passieren, dass der Server beschließt, den Client zu trennen, hauptsächlich weil er sich abgemeldet hat, um das Token ungültig zu machen und eine Abfrage in der DB dazu auffordert, oder das Auth-Token abgelaufen ist oder was auch immer.

In diesem Fall möchte ich die Serverabfrage durch den Client wiederherstellen, da sich der Benutzer möglicherweise erneut anmelden möchte und er die Rechte hat, sich erneut mit dem Server zu verbinden.

Wenn ich die Seite (Client) im Browser aktualisiere, funktioniert es in Ordnung, aber es ist eine hässliche Lösung.

Ich denke, die Ursache ist, dass die Eigenschaft "Manager.skipReconnect" nach dem Ausführen von Disconnect() auf true gesetzt wurde.

Ich habe einige Antworten auf Stackoverflow dazu gefunden, aber alle waren erfolglos, alle Dinge müssen im Client ausgeführt werden:

  • socket.io.reconnect();
  • socket.socket.reconnect(); // ??
  • socket = io.connect( ' http://127.0.0.1 :3000', ... // das erneute Aufrufen des Connect-Snippets scheint eine schlechte Idee zu sein

Könnten Sie mir in dieser Angelegenheit helfen?

Dankeschön

Hilfreichster Kommentar

Im Moment habe ich es so geschafft und es scheint stabil zu sein:

Kunde :

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

Alle 35 Kommentare

Im Moment habe ich es so geschafft und es scheint stabil zu sein:

Kunde :

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

Mit einem ähnlichen Ansatz von:

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

Dies führt leider dazu, dass der Socket das HTTP-Protokoll anstelle von Web-Sockets verwendet.

Suche immer noch nach einem guten Ansatz für eine dauerhafte Web-Socket-Verbindung.

Habe ich was übersehen???

Bin auch an einer Lösung dafür interessiert.

socket.connect()
hat bei mir mit Version 1.5.1 funktioniert. Ich hoffe, das hilft.

@sconway Kannst du uns aufklären? Jeder Code kann sein?

Hi,

Hatte die gleiche Frage und fand heraus, dass diese Lösung, die derzeit getestet wird, entweder eine robuste Lösung oder eine robuste Problemumgehung zu sein scheint ... (beide werden bereitgestellt)

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

Könnten wir dies in socket.io selbst beheben?

Ich habe auf Version 2.0.3 aktualisiert und die Standardeinstellungen für die automatische Wiederverbindung funktionierten, hier gibt es keine Probleme.

Wenn Server oder Client die Methode Disconnect() aufruft, zerstört der Client den Socket, löscht alle Event-Handler und der Manager entfernt sie aus dem verbindenden Array. Dies tritt nicht auf, wenn die Trennung aus einem anderen Grund erfolgt.
Eine großartige Problemumgehung könnte der Grundparameter sein
.on('disconnect', reason => { if(reason === 'io server disconnect') { //you should renew token or do another important things before reconnecting socket.connect(); } });
Oder viel besser prüfen, ob sich die Steckdose noch in der Verbindungsliste des Managers befindet
.on('disconnect', () => { if(socket.io.connecting.indexOf(socket) === -1){ //you should renew token or do another important things before reconnecting socket.connect(); } })

Ich habe es wie @DrLightman gemacht und es funktioniert perfekt!

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

            });
        });

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

        return this.socket;
    }
}

var socket = WebSocketServer.connect();

@DrLightman so
var io= new socketio.connect('http://192.168.43.79:3000',{'forceNew':true});

@pablodgonzalez Ich habe die gleiche Frage, Ihre Lösung funktioniert?

@programmerCs Ja, das ist es. In Produktion ohne erkannte Probleme.

Dieses Problem hat viele meiner Probleme gelöst
Danke an alle

Hatte das gleiche Problem, als ich einen Client zwingen wollte, sein Token zu aktualisieren, da es abgelaufen ist, während es mit dem Server verbunden war.

Am Ende habe ich stattdessen ein Ereignis an den Client gesendet und ihn gebeten, sein Token zu aktualisieren. Dadurch wird kein Socket geschlossen, daher werden Probleme vermieden und es funktioniert einwandfrei!

...jetzt ist es an der Zeit, das in die Produktion zu bringen! :kalter_schweiß: :grins:

Es scheint die einfachste Lösung zu sein, auf das Ereignis 'disconnect' vom Emitter zu hören und die setTimeout( )-Funktion aufzurufen, aber was ist mit Ereignissen, die der Client erstellen kann, während er vom Server getrennt wird? Es scheint, als ob es immer eine zusätzliche Prüfung durchführen muss, ob die Verbindung hergestellt ist, bevor eine Emittierung auf dem Client gesendet wird.

@qassa Wenn Sie eine Bestätigung über die Rückrufparameter verwenden. Wenn Sie stattdessen den Empfang eines Ereignisses garantieren müssen, sollten Sie nicht socket.io verwenden, sondern eine Warteschlangenbibliothek/ein Protokoll wie Moskito/mqtt oder was auch immer.
setTimeout ist eine Option, aber ein getrennter Socket (vom Server oder Client) ist ein Socket, der bald zerstört wird. Wenn Sie also eine einfache und schnelle Wiederverbindung garantieren müssen, warum sollten Sie setTimeout verwenden, wenn Sie die Socket-Objektinstanz bereits haben und connect() aufrufen können?

Jemand aus dem Projekt MUSS dies WIRKLICH DOKUMENTIEREN...

Um dies klarzustellen, trennt der Server den Client aus einem bestimmten Grund oder aufgrund eines Verlusts der Netzwerkverbindung? Wenn es sich nur um ein Netzwerk handelt, wird Socketio (Client) auf unbestimmte Zeit versuchen, sich erneut zu verbinden! , wenn es so konfiguriert ist, io=new socketio(‘http://yourserver.com’, {'forceNew':true}); wird es auf jeden Fall immer noch eine Verbindung herstellen, aber wenn Sie einen Listener vom Server trennen, rufen Sie einfach io.disconnect() auf dem Client an

Von: CxRes [mailto:[email protected]]
Gesendet: 01.02.2018 21:50
An: socketio/socket.io [email protected]
Cc: devyaz [email protected] ; Kommentar [email protected]
Betreff: Re: [socketio/socket.io] Der richtige Weg für einen Client, sich erneut zu verbinden, nachdem der Server eine socket.disconnect (true) durchgeführt hat (#2476)

Jemand aus dem Projekt MUSS dies WIRKLICH DOKUMENTIEREN...


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub https://github.com/socketio/socket.io/issues/2476#issuecomment-362381171 an oder schalten Sie den Thread stumm https://github.com/notifications/unsubscribe-auth/ ATfQSQQ1LJ90E6FqsdmiMktpp2AdoLuxks5tQhVQgaJpZM4HsVs7 . https://github.com/notifications/beacon/ATfQSYqwkgtrHZk9FASNZUl69ps9ZYYCks5tQhVQgaJpZM4HsVs7.gif

@devyaz ich liebe dich

Die Dokumentation wurde mit der Antwort von @pablodgonzalez aktualisiert: https://github.com/socketio/socket.io-client/commit/afb952d854e1d8728ce07b7c3a9f0dee2a61ef4e

Danke vielmals!

Verwenden Sie die Version

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

Mit einem ähnlichen Ansatz von:

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

Dies führt leider dazu, dass der Socket das HTTP-Protokoll anstelle von Web-Sockets verwendet.

Suche immer noch nach einem guten Ansatz für eine dauerhafte Web-Socket-Verbindung.

Habe ich was übersehen???

wss:// verwenden

Mit einem ähnlichen Ansatz von:

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

Dies führt leider dazu, dass der Socket das HTTP-Protokoll anstelle von Web-Sockets verwendet.
Suche immer noch nach einem guten Ansatz für eine dauerhafte Web-Socket-Verbindung.
Habe ich was übersehen???

wss:// verwenden

hallo,bro.how kann sein, dass, wenn nur wss.it nur als persistente Web-Socket-Verbindung funktioniert, die gleiche Frage zu halten und schnell reconnet mit ws nicht abfragen.

Wenn Server oder Client die Methode Disconnect() aufruft, zerstört der Client den Socket, löscht alle Event-Handler und der Manager entfernt sie aus dem verbindenden Array. Dies tritt nicht auf, wenn die Trennung aus einem anderen Grund erfolgt.
Eine großartige Problemumgehung könnte der Grundparameter sein

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

Oder viel besser prüfen, ob sich die Steckdose noch in der Verbindungsliste des Managers befindet

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

Können Sie erläutern, warum es besser ist, zu überprüfen, ob sich der Socket noch in der Verbindungsliste des Managers befindet? Das aktualisierte Dokument hat nur Ihre erste Lösung verwendet, die darin besteht, den Grund für die Trennung zu überprüfen. Vielen Dank.

Hallo @emclab , nur weil die Entwickler in neueren Versionen einen neuen Grund hinzufügen und für deinen Fall "der Grund" nicht wichtig ist, dann suche einfach nach dem Socket in der Verbindungsliste. wenn es nicht da ist, müssen Sie die Verbindung manuell wiederherstellen.
In einigen Fällen ist es wichtig, den Grund zu kennen, und es ist der stärkere Fall, lesen und handeln Sie entsprechend, aber vielleicht ist es nicht der häufigste.
Haftungsausschluss: Wenn Sie sich für den zweiten Weg entscheiden, sind Sie vor Refactorings oder einigen Änderungen der Mechanismen in neueren Versionen nicht sicher, daher ist es nicht viel besser, aber viel einfacher.
Grüße!

Ich bin nicht in der Lage, die Verbindung zur Ionenanwendung zu trennen. Ich habe socket.on in den Konstruktor der allgemeinen Seite in Anbietern. Ich möchte den Socket zu einer Funktion in derselben Datei trennen, von der aus die Anwendungsabmeldung aufgerufen wird.

Aber ich kann die Steckdose trennen. Ich bin multiple socket.on('event') auf mehrere Emit in Anwendung.
Kann mir jemand weiterhelfen?

Socket.disconnect() sollte tun

Am Mo, 11 Nov 2019 06:16 schrieb krunal9421, [email protected] :

Ich bin nicht in der Lage, die Verbindung zur Ionenanwendung zu trennen. Ich habe
socket.on in den Konstruktor der allgemeinen Seite in Providern. ich will
Trennen Sie den Socket in eine Funktion in derselben Datei, von der aus die Anwendung
Ausloggen wird aufgerufen.

Aber ich kann die Steckdose trennen. Ich bin Mehrfachsteckdose.on('Ereignis')
bei mehreren in die Anwendung emittieren.
Kann mir jemand weiterhelfen?


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/socketio/socket.io/issues/2476?email_source=notifications&email_token=AE35ASNI2K4DWOB4P2HPSATQTDMC7A5CNFSM4B5RLM52YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNSMVZ
oder abmelden
https://github.com/notifications/unsubscribe-auth/AE35ASJPORGOSYQAEJEHHG3QTDMC7ANCNFSM4B5RLM5Q
.

@devyaz Ich kann den Socket nicht mit socket.disconnect() trennen.
Ich habe meinen Beispielcode mit diesem geteilt.
https://i.stack.imgur.com/wrIEv.png.

Ich habe Code in eine gemeinsame Datei geschrieben.

Versuchen Sie, die Verbindung zur Server- oder Benutzerseite zu trennen? dh Server sollte
Benutzer trennen. Denn wenn der Server den Client verliert, löst er eine Verbindung aus
Veranstaltung. Aber der Client kann die Verbindung zum Server trennen, indem er anruft
socket.disconnect

Am Mi, 20 Nov 2019 05:39 schrieb krunal9421, [email protected] :

@devyaz https://github.com/devyaz Ich kann die Steckdose nicht trennen
mit socket.disconnect().
Ich habe meinen Beispielcode mit diesem geteilt.
https://i.stack.imgur.com/wrIEv.png.

Ich habe Code in eine gemeinsame Datei geschrieben.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/socketio/socket.io/issues/2476?email_source=notifications&email_token=AE35ASK4NY4SKG5JWSBDKCTQUSWNVA5CNFSM4B5RLM52YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63TLNWW2H55JLOKTLNVA5CNFSM4B5RLM52YY3PNVWWK5
oder abmelden
https://github.com/notifications/unsubscribe-auth/AE35ASIFTISGTIAQQ7UKCJDQUSWNVANCNFSM4B5RLM5Q
.

dies auf der Clientseite verwenden.

Mache this.socketstatus.disconnect() in deiner Logout-Funktion und ich denke
Sie sollten die Funktion ".on("connected",.....)" entfernen.

Am Freitag, den 22. November 2019, 11:50 Uhr schrieb krunal9421, [email protected] :

dies auf der Clientseite verwenden.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/socketio/socket.io/issues/2476?email_source=notifications&email_token=AE35ASJTREAYRMF4THBK3FDQU6TOLA5CNFSM4B5RLM52YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJ650com
oder abmelden
https://github.com/notifications/unsubscribe-auth/AE35ASJGKVGVUQNK454C63DQU6TOLANCNFSM4B5RLM5Q
.

Nachdem die Verbindung unterbrochen wurde, verbindet sich Socket erneut mit dem Server. Danach wird weiterhin _io.socket.engineio.client.EngineIOException: xhr post error_ in Android angezeigt .
Die meisten Antworten von StackOverflow funktionieren nicht.
Ich stecke mit diesem Problem fest T_T.... Helfen Sie mir bitte!

Ich versuche, diesen Code in meine node.js + Javascript-Wepapp zu implementieren, aber wenn der Browser meines Telefons im Hintergrund, in einem inaktiven Tab oder gesperrtem Bildschirm ist, wird er nach einigen Minuten getrennt.

Ich habe versucht, eine Verbindung zu einem Socket wieder herzustellen, wenn er getrennt ist (mit ping timeout oder transport closed Antworten), aber es ist unmöglich. Ist das ein normales Verhalten bei Telefonbrowsern? weil in Laptop- oder Desktop-Browsern wie erwartet funktioniert.

Kann mir jemand helfen?

Vielen Dank

Hallo @asiermusa, aber im Web müssen Sie einen Web-Worker verwenden, um eine Unterbrechung des Prozesses zu vermeiden. Ich weiß ehrlich gesagt nicht, ob es ausreicht, um das zu erreichen.

Danke schön!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen