База данных Firebase Realtime дает неверное значение смещения времени сервера - PullRequest
0 голосов
/ 16 мая 2018

Я использую следующий код в моем PWA для вычисления перекоса часов клиента относительно серверов базы данных Firebase Realtime на основе документов: -

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

Однако проблема в том, что на некоторых устройствах я получаю странные значения, такие как -13181 для смещения, что делает его почти на 13 секунд! Следовательно, таймер обратного отсчета 20 секунд на этом устройстве начинается с 7 секунд, потому что в действительности смещение намного ниже. Вчера одна машина постоянно получала вышеуказанное значение (-13181), хотя раньше она работала нормально. Есть ли причина, по которой устройства в одной сети будут сообщать о таких огромных различиях в значении временного смещения? Как я могу исправить эту проблему? Таймер обратного отсчета, синхронизируемый между различными устройствами, очень важен для моего приложения.

1 Ответ

0 голосов
/ 21 мая 2018

Добавляя контекст из нашего вчерашнего разговора, вы сказали:

Мы создали приложение для викторины, в котором могут играть даже тысячи людей. в режиме реального времени, и поэтому все должны видеть одно и то же значение в обратном отсчете таймер. Наша логика работает довольно хорошо, за исключением того факта, что редко я получаю странные значения смещения.

Насколько это возможно, вы не хотите зависеть от часов клиента. Уже существует некоторая разница, неизбежная в зависимости от качества сети людей и расстояния от сервера, так что, как вы видели, добавление ненадежных локальных часов может усугубить это. Сроки для онлайн-игр - задача не из легких, и я не буду претендовать на лучшее решение, но вот совет:

Иметь источник правды, скорее всего, сервер, который отслеживает оставшееся время в игре и обновляет его в базе данных. Вы можете использовать Firebase Admin SDK для доступа к базе данных с вашего сервера, что может быть тем, как вы уже вводите отметку времени прямо сейчас.

Запись в базу данных из Admin SDK будет выглядеть примерно так:

admin.database().ref(".info/timeRemaining").set({
  time_remaining: time_remaining
});

Где time_remaining будет временем, которое вы будете обновлять каждую секунду.

Тогда на клиенте вместо отслеживания смещения остается только оставшееся время.

var offsetRef = firebase.database().ref(".info/timeRemaining");
offsetRef.on("value", function(snap) {
  var offset = snap.val();
  // do what you will
});

Тогда у вас могут быть правила на клиенте, которые заканчивают игру на 0. Конечно, разработчики могли бы найти способы обойти это, поэтому, если это возможно, было бы лучше включить строгую проверку. Если клиенты также пишут в базу данных, но вы не хотите, чтобы они могли это делать после того, как истек срок, одним из вариантов является использование правил. Теперь ваши правила будут выглядеть по-разному в зависимости от вашей структуры данных. Я просто размышляю о применении записей к любому ребенку с ".info", что, вероятно, не совсем то, что вам нужно.

{
  "rules": {
    ".info": {
      "$info": {
        ".read": "auth != null",
        // writes can only happen before the timer reaches 0
        ".write": "data.parent().child('time_remaining').val() > 0"
      }
    }
  }
}

Это правило позволяет пользователям записывать в это местоположение только тогда, когда значение time_remaining больше 0. Если они попытаются выполнить запись после этого, будет возвращена ошибка, и вы можете обработать ее отображение на клиенте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...