Ta strona została przetłumaczona przez Cloud Translation API.
Switch to English

Włączanie funkcji offline w JavaScript

Aplikacje Firebase działają nawet wtedy, gdy Twoja aplikacja tymczasowo utraci połączenie sieciowe. Udostępniamy kilka narzędzi do monitorowania obecności i synchronizowania stanu lokalnego ze stanem serwera, które zostały przedstawione w tym dokumencie.

Zarządzanie obecnością

W aplikacjach czasu rzeczywistego często przydatne jest wykrywanie, kiedy klienci łączą się i rozłączają. Na przykład możesz chcieć oznaczyć użytkownika jako „offline”, gdy jego klient się rozłączy.

Klienci bazy danych Firebase zapewniają proste prymitywy, których można użyć do zapisu w bazie danych, gdy klient rozłącza się z serwerami bazy danych Firebase. Te aktualizacje są wykonywane niezależnie od tego, czy klient rozłącza się poprawnie, czy nie, więc można na nich polegać, aby wyczyścić dane, nawet jeśli połączenie zostanie zerwane lub nastąpi awaria klienta. Wszystkie operacje zapisu, w tym ustawianie, aktualizowanie i usuwanie, mogą być wykonywane po rozłączeniu.

Oto prosty przykład zapisywania danych po rozłączeniu przy użyciu prymitywu onDisconnect :

var presenceRef = firebase.database().ref("disconnectmessage");
// Write a string when this client loses connection
presenceRef.onDisconnect().set("I disconnected!");

Jak działa onDisconnect

Po ustanowieniu operacji onDisconnect() operacja onDisconnect() na serwerze bazy danych czasu rzeczywistego Firebase. Serwer sprawdza zabezpieczenia, aby upewnić się, że użytkownik może wykonać żądane zdarzenie zapisu i informuje aplikację, jeśli jest ono nieprawidłowe. Serwer następnie monitoruje połączenie. Jeśli w dowolnym momencie połączenie przekroczy limit czasu lub zostanie aktywnie zamknięte przez klienta bazy danych czasu rzeczywistego, serwer sprawdza zabezpieczenia po raz drugi (aby upewnić się, że operacja jest nadal prawidłowa), a następnie wywołuje zdarzenie.

Twoja aplikacja może użyć wywołania zwrotnego w operacji zapisu, aby upewnić się, że onDisconnect został poprawnie podłączony:

presenceRef.onDisconnect().remove((err) => {
  if (err) {
    console.error("could not establish onDisconnect event", err);
  }
});

Zdarzenie onDisconnect można również anulować, wywołując .cancel() :

var onDisconnectRef = presenceRef.onDisconnect();
onDisconnectRef.set("I disconnected");
// some time later when we change our minds
onDisconnectRef.cancel();

Wykrywanie stanu połączenia

W przypadku wielu funkcji związanych z obecnością przydatna jest informacja, czy aplikacja jest online, czy offline. Baza danych czasu rzeczywistego /.info/connected zapewnia specjalną lokalizację pod adresem /.info/connected która jest aktualizowana za każdym razem, gdy zmienia się stan połączenia klienta Bazy danych czasu rzeczywistego /.info/connected . Oto przykład:

var connectedRef = firebase.database().ref(".info/connected");
connectedRef.on("value", (snap) => {
  if (snap.val() === true) {
    console.log("connected");
  } else {
    console.log("not connected");
  }
});

/.info/connected to wartość logiczna, która nie jest synchronizowana między klientami bazy danych czasu rzeczywistego, ponieważ zależy od stanu klienta. Innymi słowy, jeśli jeden klient odczyta /.info/connected jako fałsz, nie gwarantuje to, że oddzielny klient również odczyta fałsz.

Obsługa opóźnień

Sygnatury czasowe serwera

Serwery bazy danych czasu rzeczywistego Firebase zapewniają mechanizm wstawiania znaczników czasu wygenerowanych na serwerze jako dane. Ta funkcja, w połączeniu z onDisconnect , zapewnia łatwy sposób niezawodnego odnotowywania czasu, w którym klient bazy danych czasu rzeczywistego rozłączył się:

var userLastOnlineRef = firebase.database().ref("users/joe/lastOnline");
userLastOnlineRef.onDisconnect().set(firebase.database.ServerValue.TIMESTAMP);

Pochylenie zegara

Chociaż firebase.database.ServerValue.TIMESTAMP jest znacznie dokładniejszy i preferowany dla większości operacji odczytu / zapisu, czasami może być przydatne oszacowanie przesunięcia zegara klienta w odniesieniu do serwerów Firebase Realtime Database. Możesz dołączyć wywołanie zwrotne do lokalizacji /.info/serverTimeOffset aby uzyskać wartość w milisekundach, którą klienci Firebase Realtime Database dodają do lokalnego raportowanego czasu (czas epoki w milisekundach) w celu oszacowania czasu serwera. Zwróć uwagę, że na dokładność tego przesunięcia może wpływać opóźnienie w sieci, dlatego jest przydatne przede wszystkim do wykrywania dużych (> 1 sekundy) rozbieżności w czasie zegara.

var offsetRef = firebase.database().ref(".info/serverTimeOffset");
offsetRef.on("value", (snap) => {
  var offset = snap.val();
  var estimatedServerTimeMs = new Date().getTime() + offset;
});

Przykładowa aplikacja Presence

Łącząc operacje rozłączania z monitorowaniem stanu połączenia i sygnaturami czasowymi serwera, można zbudować system obecności użytkowników. W tym systemie każdy użytkownik przechowuje dane w lokalizacji bazy danych, aby wskazać, czy klient bazy danych czasu rzeczywistego jest online. Klienci ustawiają tę lokalizację na true, gdy przechodzą do trybu online i sygnaturę czasową, gdy się rozłączają. Ta sygnatura czasowa wskazuje, kiedy ostatnio dany użytkownik był online.

Należy pamiętać, że aplikacja powinna kolejkować operacje rozłączania, zanim użytkownik zostanie oznaczony w trybie online, aby uniknąć sytuacji wyścigu w przypadku utraty połączenia sieciowego klienta, zanim oba polecenia będą mogły zostać wysłane na serwer.

Oto prosty system obecności użytkowników:

// Since I can connect from multiple devices or browser tabs, we store each connection instance separately
// any time that connectionsRef's value is null (i.e. has no children) I am offline
var myConnectionsRef = firebase.database().ref('users/joe/connections');

// stores the timestamp of my last disconnect (the last time I was seen online)
var lastOnlineRef = firebase.database().ref('users/joe/lastOnline');

var connectedRef = firebase.database().ref('.info/connected');
connectedRef.on('value', (snap) => {
  if (snap.val() === true) {
    // We're connected (or reconnected)! Do anything here that should happen only if online (or on reconnect)
    var con = myConnectionsRef.push();

    // When I disconnect, remove this device
    con.onDisconnect().remove();

    // Add this device to my connections list
    // this value could contain info about the device or a timestamp too
    con.set(true);

    // When I disconnect, update the last time I was seen online
    lastOnlineRef.onDisconnect().set(firebase.database.ServerValue.TIMESTAMP);
  }
});