2013-06-12 4 views
8

Ich habe Firebase ausgiebig genutzt und sehe immer noch nur ein echtes Problem: onDisconnect ist meiner Erfahrung nach nicht zu 100% zuverlässig.Firebase onDisconnect nicht 100% zuverlässig jetzt?

Wenn Sie einen Computer schließen, ohne das Fenster zuerst zu schließen oder den Browser zu beenden, haben Sie manchmal den "Garbage Collector", der Ihre onDisconnect-Verbindung ausführt, manchmal nicht.

Meine Frage ist folgende: Ich ich im Grunde einfach nicht /.connected jetzt verwenden, verwenden Sie eine einfache

userRef.set('status', 1); 
userRef.onDisconnect().update({ 'status' : 0 }); 

Gibt es etwas falsch mit diesem Ansatz? Stimmen wir zu, dass die Update-Parameter zum Zeitpunkt der Ausführung der Zeile und nicht vor dem Entladen des Fensters an den Server übergeben werden?

NB: Ich bin zufällig zu versuchen, ein Multi-Fenster-Status zu halten, die folgende Vorgehensweise mit dem Status bei 1 zu halten, wenn ein anderes Fenster geschlossen ist:

userRef.child('status').on('value', function(snap) { 
    if (snap.val() != 1) { 
    userRef.set('status', 1); 
    } 
}); 

Ich tue dies nicht, wie das sein könnte verwandt, aber ...

MEINE LÖSUNG: Tatsächlich hatte ich gerade den Teil verfehlt, wo Sie erfahren, dass onDisconnect nur einmal ausgelöst wird. Um eine dauerhafte onDisconnect zu erhalten, müssen Sie grundlegende Persistenz implementieren.

Helpers.onConnected = function(callback) { 
    var connectedRef = lm.newFirebase('.info/connected'); 
    var fn = connectedRef.on('value', function(snap) { 
     if (snap.val() === true) { 
      if (callback) callback(); 
     } 
    }); 
    var returned = {}; 
    returned.cancel = function() { 
     connectedRef.off('value', fn); 
    }; 
    return returned; 
};  

Einfacher Anwendungsfall:

 this._onConnected = lm.helpers.onConnected(function() { 
      this.firebase.onDisconnect().update({ 'tu': 0 }); 
     }.bind(this)); 

Und dann abzubrechen:

 if (this._onConnected) this._onConnected.cancel(); 
     this.firebase.onDisconnect().cancel(); 

Antwort

5

Sie sollten die OnDisconnect() Betrieb immer anrufen, bevor Sie den Satz() Betrieb nennen. Auf diese Weise enden die Zombie-Daten nicht, wenn die Verbindung zwischen den beiden verloren geht.

Beachten Sie auch, dass Sie in dem Fall, in dem die Netzwerkverbindung nicht sauber beendet wird, möglicherweise auf ein TCP-Timeout warten müssen, bevor wir den Benutzer als ausgeblendet erkennen und die Aufräumung der Verbindung auslösen können. Die Bereinigung wird ausgeführt, es kann jedoch einige Minuten dauern.

+2

Das Problem ist, dass ich immer noch etwa 20% von onDisconnect bekomme, die leider nie angerufen werden, was dazu führt, dass Leute immer verbunden zu sein scheinen. Haben Sie eine Vorstellung davon, wie Sie das Geschehen verstehen können, da es zu 100% sicher ist, dass es immer noch eine Verbindung für einige Minuten gibt, wenn onDisconnect aufgerufen wird? – cwehrung

+1

Wie lange warten Sie, nachdem der Client die Verbindung getrennt hat? In extremen Fällen kann es bis zu 5 Minuten dauern. Außerdem - haben Sie vielleicht Sicherheitsregeln, die den Trennvorgang blockieren? Ein Testfall wäre auch hilfreich. Hast du einen Link zu einem super-einfachen Testfall? –

+3

Andrew, ich habe endlich die Quelle meines Problems gefunden. Mein Fehler: Ich habe nie wirklich gemerkt, dass onDisconnect nur beim ersten Verbindungsabbau angerufen wurde. Dies erklärt all die Fehler, die wir haben ... Ich würde es definitiv rot + fett auf Ihrer Website setzen. – cwehrung