2013-06-12 3 views
8

Utilizzo estesamente Firebase e continuo ad affrontare solo un problema reale: onDisconnect non è affidabile al 100% nella mia esperienza.Firebase onDisconnect non affidabile al 100% ora?

Se chiudi un computer senza chiudere prima la finestra o uccidi il browser, a volte il "garbage collector" ottiene l'onDisconnect eseguito, a volte no.

La mia domanda è la seguente: Ho appena non uso /.connected per ora, io fondamentalmente uso un semplice

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

C'è qualcosa di sbagliato in questo approccio? Siamo d'accordo che i parametri di aggiornamento vengono passati al server nel momento in cui viene eseguita la riga e non prima che la finestra venga scaricata?

NB: mi capita di cercare di mantenere uno stato multi-finestra, utilizzando il seguente approccio per mantenere lo stato a 1 se un'altra finestra è chiusa:

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

io non faccio come questo potrebbe essere relativo, ma ...

LA MIA SOLUZIONE: Infatti, avevo appena perso la parte in cui si apprende che onDisconnect viene attivato solo una volta. Per ottenere una disconnessione persistente, è necessario implementare la persistenza di base.

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

semplice caso d'uso:

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

E poi per annullare:

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

risposta

5

Si deve sempre chiamare l'operazione OnDisconnect() prima di chiamare alla soglia di funzionamento(). In questo modo se la connessione viene persa tra i due non si finisce con i dati zombie.

Si noti inoltre che nel caso in cui la connessione di rete non viene eliminata in modo pulito, potrebbe essere necessario attendere un timeout TCP prima che sia possibile rilevare l'utente come andato e attivare la disconnessione. La pulizia si verificherà, ma potrebbero essere necessari alcuni minuti.

+2

Il problema è che continuo a ricevere circa il 20% di onDisconnect che non viene mai chiamato, con il risultato che persone sembrano essere collegate per sempre. Hai idea di un modo per capire cosa sta accadendo in quanto è sicuro al 100% che ci sia ancora una connessione per almeno alcuni minuti quando viene chiamato onDisconnect? – cwehrung

+1

Quanto tempo stai aspettando dopo che il client si disconnette? In alcuni casi estremi potrebbero essere necessari fino a 5 minuti. Inoltre, hai forse delle regole di sicurezza che bloccano l'operazione di disconnessione? Un test case sarebbe utile pure. Hai un collegamento con un caso di test super-semplice? –

+3

Andrew, ho finalmente trovato la fonte del mio problema. Il mio errore: non mi sono mai reso conto che onDisconnect è stato chiamato solo la prima volta che sei disconnesso. Questo spiega tutti i bug che abbiamo ... Lo metterei sicuramente in rosso + grassetto sul tuo sito web. – cwehrung