Google Cloud Functions +实时数据库非常慢

时间:2019-04-02 09:29:24

标签: node.js firebase firebase-realtime-database google-cloud-functions

我正在开发Unity中用于移动设备的多人文字游戏。我一直在使用GameSparks作为后端,但是觉得它并没有给我我想要的对该项目的控制权。环顾四周后,我决定使用Firebase。感觉这是一个不错的决定,但是现在我在使用数据库+云功能时遇到了一些严重的问题

游戏具有回合制模式,您可以在此模式下进行回合,并在对手结束后获得通知。一轮回合是通过cloudscript调用上传的,仅包含必要的数据。然后,新的游戏状态会在cloudscript中拼凑在一起,并更新游戏数据库条目(activeCasualGames / {gameId})。完成此操作后,我用一些有关游戏的基本信息更新了gameInfo(activeCasualGamesInfo / {gameId})条目,然后发送云消息以通知对手轮到他们了。

发送的数据仅为32 kb,并且没有对代码进行复杂的更改(请参见下面的云功能代码)。此时,游戏的完整数据库条目最大约为100kb,但是从服务器发送回合到游戏的更新时间以及通知对手的时间从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 :(得分:0)

使用Firebase Cloud Function +实时数据库时,您必须考虑一些事项。 https://godbolt.org/z/nLPlv1问题可能有助于解决无服务器性能问题,例如This。另外,我认为代码本身可以重构为减少对实时数据库的调用,因为每个外部请求都可能需要时间。一些技巧是使用更多本地存储的资源(在内存,浏览器缓存等中)并使用一些全局变量。