2013-06-12 9 views
8

Używam intensywnie Firebase i wciąż napotykam tylko jeden problem: onDisconnect nie jest w 100% niezawodny na moim doświadczeniu.Firebase onDisconnect nie jest teraz w 100% wiarygodny?

Jeśli zamkniesz okno bez zamykania okna lub zabijesz przeglądarkę, masz czasami do czynienia z "śmieciarzem", który uruchamia narzędzie onDisconnect, a czasami nie.

Moje pytanie jest następujące: Po prostu nie używaj /.connected teraz, ja po prostu użyć prosty

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

Czy jest coś nie w porządku z tym podejściem? Czy zgadzamy się, że parametry aktualizacji są przekazywane do serwera w momencie wykonywania linii, a nie przed wyładowaniem okna?

NB: Tak się składa, aby utrzymać status wielo-okienkowy, stosując następujące metody, aby utrzymać stan na 1, jeżeli kolejne okno jest zamknięte:

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

nie mam tego jak to może być powiązane, ale ...

MOJE ROZWIĄZANIE: W rzeczywistości właśnie przegapiłem część, w której dowiadujesz się, że onDisconnect jest uruchamiany tylko raz. Aby uzyskać trwałe narzędzie onDisconnect, musisz zaimplementować podstawową trwałość.

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

Prosty przypadek użycia:

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

A następnie, aby anulować:

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

Odpowiedz

5

zawsze należy wezwać onDisconnect() operację przed zadzwonić do set() operacji. W ten sposób, jeśli połączenie zostanie utracone między tymi dwoma, których nie otrzymasz z danymi o zombie.

Należy również pamiętać, że w przypadku, gdy połączenie sieciowe nie jest czysto zabite, być może trzeba będzie poczekać na przekroczenie limitu czasu TCP, zanim będziemy w stanie wykryć użytkownika jako nieobecny i wyzwolić czyszczenie rozłączenia. Oczyszczanie nastąpi, ale może potrwać kilka minut.

+2

Problem polega na tym, że wciąż dostaję około 20% wiadomości onDisconnect, które nigdy nie są wywoływane niestety, co powoduje, że ludzie wydają się być na zawsze w kontakcie. Czy masz jakiś pomysł na zrozumienie, co się dzieje, ponieważ jest w 100% pewien, że połączenie jest nawiązywane przez co najmniej kilka minut, gdy wywoływany jest onDisconnect? – cwehrung

+1

Jak długo czekasz po rozłączeniu klienta? W skrajnych przypadkach może to potrwać do 5 minut. Również - czy może masz reguły bezpieczeństwa, które blokują operację rozłączania? Przydałby się również test. Czy masz link do super-prostego testu? –

+3

Andrew, w końcu znalazłem źródło mojego problemu. Mój błąd: nigdy naprawdę nie zdawałem sobie sprawy, że na Dysconnect byłam nazywana tylko przy pierwszym rozłączeniu. To wyjaśnia wszystkie błędy, które mamy ... Zdecydowanie umieściłbym to na czerwono i pogrubienie na twojej stronie. – cwehrung