Облачные функции Google + база данных в реальном времени очень медленно - PullRequest
0 голосов
/ 02 апреля 2019

Я разрабатываю многопользовательскую словесную игру для мобильных устройств в Unity. Я использовал GameSparks в качестве бэкэнда, но чувствовал, что он не дает мне контроль над проектом. Посмотрев немного, я решил пойти с Firebase. Это было хорошее решение, но теперь я испытываю серьезную медлительность с базой данных + Cloud Functions

В игре есть пошаговый режим, в котором вы играете в раунд и получаете уведомление, когда оппонент закончил. Раунд загружается через облачный вызов, содержащий только необходимые данные. Новое состояние игры затем объединяется в облачном сценарии и обновляется запись в базе данных игры (activeCasualGames / {gameId}). После того, как это сделано, я обновляю запись gameInfo (activeCasualGamesInfo / {gameId}) основной информацией об игре, а затем отправляю облачное сообщение, чтобы уведомить оппонента о том, что его очередь.

Отправленные данные составляют всего 32 КБ, и в код не вносятся сложные изменения (см. Код функции облака ниже). На этом этапе полная запись базы данных для игры будет около 100 КБ максимум, но время от отправки раунда до обновления игры на сервере и уведомления оппонента колеблется от 50 секунд до более минуты. В GameSparks та же самая операция может занять несколько секунд.

Кто-нибудь еще испытывает такую ​​медлительность с Firebase? Я сделал какую-то ошибку в функции облачного скрипта, или это производительность, которую я должен ожидать? В игре также есть живой режим, который я еще не начал реализовывать в Firebase, и с таким лагом я не чувствую, что он будет работать слишком хорошо

Заранее большое спасибо!

exports.uploadCasualGameRound = functions.https.onCall(
  (roundUploadData, response) => {
    const roundData = JSON.parse(roundUploadData);

    const updatedGameData = JSON.parse(roundData.gameData);
    const updatedGameInfo = JSON.parse(roundData.gameInfo);

    console.log("game data object:");
    console.log(updatedGameData);

    console.log("game info:");
    console.log(updatedGameInfo);

    const gameId = updatedGameData.gameId;

    console.log("updating game with id: " + gameId);

    admin
      .database()
      .ref("/activeCasualGames/" + gameId)
      .once("value")
      .then(function(snapshot: { val: any }) {
        let game = snapshot.val();
        console.log("old game:");
        console.log(game);

        const isNewGame = (game as boolean) === true;

        if (isNewGame === false) {
          console.log("THIS IS AN EXISTING GAME!");
        } else {
          console.log("THIS IS A NEW GAME!");
        }

        // make the end state of the currently stored TurnBasedGameData the beginning state of the uploaded one (limits the upload of data and prevents timeout errors)
        if (isNewGame === true) {
          updatedGameData.gameStateRoundStart.playerOneRounds =
            updatedGameData.gameStateRoundEnd.playerOneRounds;
        } else {
          // Player one rounds are not uploaded by player two, and vice versa. Compensate for this here:
          if (updatedGameData.whoseTurn === updatedGameData.playerTwoId) {
            updatedGameData.gameStateRoundEnd.playerTwoRounds =
              game.gameStateRoundEnd.playerTwoRounds;
          } else {
            updatedGameData.gameStateRoundEnd.playerOneRounds =
              game.gameStateRoundEnd.playerOneRounds;
          }

          updatedGameData.gameStateRoundStart = game.gameStateRoundEnd;
        }

        game = updatedGameData;

        console.log("Game after update:");
        console.log(game);

        // game.lastRoundFinishedDate = Date.now();
        game.finalRoundWatchedByOtherPlayer = false;

        admin
          .database()
          .ref("/activeCasualGames/" + gameId)
          .set(game)
          .then(() => {
            updatedGameInfo.roundUploaded = true;
            return admin
              .database()
              .ref("/activeCasualGamesInfo/" + gameId)
              .set(updatedGameInfo)
              .then(() => {
               exports.sendOpponentFinishedCasualGameRoundMessage(gameId, updatedGameInfo.lastPlayer, updatedGameInfo.whoseTurn);
                return true;
              });
          });
      });
  }
);

1 Ответ

0 голосов
/ 02 апреля 2019

Есть некоторые вещи, которые вы должны учитывать при использовании Firebase Cloud Function + Realtime Database. Этот вопрос может помочь по поводу проблем с производительностью без сервера, таких как холодный запуск .Кроме того, я думаю, что сам код может быть подвергнут рефакторингу для меньшего количества обращений к базе данных реального времени, так как каждый внешний запрос может занимать время.Некоторые советы - использовать больше локально хранящихся ресурсов (в памяти, кеше браузера и т. Д.) И использовать некоторые глобальные переменные.

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