Firebase loading too slow for tile based game

I am creating a 2d tile for iOS with Fast and Firebase. Since the world is big, I designed it so that I only subscribe to the tiles that are on the screen. That is, instead of adding listeners for all 10,000x10,000 fragments, I add them only to fragments on the screen. When a player moves, I de-register old listeners and register new ones. I added a little buffer zone around the edge of the screen, in the hope that everything would be loaded enough by the time it moves around the screen. Unfortunately, often there is a fairly significant lag behind Firebase that this strategy simply does not work. On suboptimal Internet connections, you can continue to go to the "unloaded world", taking a few seconds to download the missing fragments.

Here it is, though: other iOS MMO games on the same connection and the same device work fine. This is not a terrible connection. It makes me suspect my implementation, or Firebase itself is to blame.

Basically, I expect a one time event for about 20 fragments every time I take a step. The step takes about 1/4 of a second, so every second I request about 100 items from Firebase. However, I cannot think of a better way. The Firebase documentation suggests that this should not be a problem, as it is all one socket connection. I could “load” objects in, say, 10x10 blocks, which would mean that I would subscribe to fewer objects, but it would also be more useless in terms of complete data transfer. If the socket connection is indeed optimized, the overall data transfer should be the only bottleneck, implying that this strategy will be wrong.

change

, . -1, . , , . , . http://forevermaze.inzania.com/videos/FirebaseLag.mov (nb, . , , . .)

, . . , , 20 , . . MiFi LTE- , .

  /**
   * Given a path to a firebase object, get the snapshot with a timeout.
   */
  static func loadSnapshot(firebasePath: String!) -> Promise<FDataSnapshot?> {
    let (promise, fulfill, _) = Promise<FDataSnapshot?>.pendingPromise()
    let connection = Firebase(url: Config.firebaseUrl + firebasePath)
    connection.observeSingleEventOfType(.Value, withBlock: { snapshot in
      if !promise.resolved {
        fulfill(snapshot)
      }
    })
    after(Config.timeout).then { () -> Void in
      if !promise.resolved {
        DDLogWarn("[TIMEOUT] [FIREBASE-READ] \(firebasePath)")
        fulfill(nil)
        //reject(Errors.network)
      }
    }
    return promise
  }

[ROOT]/tiles/[X]x[Y]. , (.. ), . Firebase: enter image description here

edit2

. 100- XCTestCase : http://forevermaze.com/code/LagTests.swift

:

  • Swift ( , Firebase)
  • firebaseUrl URL (.. https://MyProject.firebaseio.com)
  • testSetupDatabase() ,
  • testWalking(), . . , - 2 .

. , LTE MiFi . 2 seconds -, , 10 tile (0,2 * 10 = 2 ). , LTE, , 10 (!!): error: -[ForeverMazeTests.LagTests testWalking] : XCTAssertTrue failed - Tile 2x20 took 9.50058007240295

+4
1

, 15-20 , 3G-. 1-2 , , , .

JavaScript, , . : http://jsbin.com/dijiba/edit?js,console

var ref = new Firebase(URL);
var tilesPerStep = 20;
var stepsToTake = 100;

function testWalking() {
  var startTime = Date.now();
  var promises = [];
  for (var x=0; x < stepsToTake; x++) {
    promises.push(testStep(x));
  }
  Promise.all(promises).then(function() {
    console.log('All '+promises.length+' steps done in '+(Date.now()-startTime)+'ms');
  });
}

function testStep(x) {
  var result = new Promise(function(resolve, reject){
    var tiles = ref.child("/tiles_test");
    var loading = 0;
    var startTime = Date.now();
    console.log('Start loading step '+x);

    for (var y=0; y < tilesPerStep; y++) {
      loading ++;
      tiles.child(x+'x'+y).once('value', function(snapshot) {
        var time = Date.now() - startTime;
        loading--;
        if (loading === 0) {
          console.log('Step '+x+' took '+(Date.now()-startTime)+'ms');
          resolve(Date.now() - startTime);
        }
      });
    }
  });
  return result;
}

testWalking();

, - , . , - , .

Firebase , . , . " , ".

10 :

"Start loading step 0"
"Start loading step 1"
"Start loading step 2"
"Start loading step 3"
"Start loading step 4"
"Start loading step 5"
"Start loading step 6"
"Start loading step 7"
"Start loading step 8"
"Start loading step 9"
"Step 0 took 7930ms"
"Step 1 took 7929ms"
"Step 2 took 7948ms"
"Step 3 took 8594ms"
"Step 4 took 8669ms"
"Step 5 took 9141ms"
"Step 6 took 9851ms"
"Step 7 took 10365ms"
"Step 8 took 10425ms"
"Step 9 took 11520ms"
"All 10 steps done in 11579ms"

, , , , , . , , . , , -.

. , ( WebSocket Firebase), ( , 20 ).

, , , . . , , 10x10 "". 10 .

Update

, . :

func testWalking() {
    let expectation = expectationWithDescription("Load tiles")
    let maxTime = self.timeLimit + self.stepTime * Double(stepsToTake)

    let startTime = NSDate().timeIntervalSince1970

    for (var x=0; x<stepsToTake; x++) {
        let delay = Double(x) * stepTime
        let data = ["x":x, "ex": expectation]
        stepsRemaining++
        NSTimer.scheduledTimerWithTimeInterval(0, target: self, selector: Selector("testStep:"), userInfo: data, repeats: false)
    }
    waitForExpectationsWithTimeout(maxTime) { error in
        let time = NSDate().timeIntervalSince1970 - startTime
        print("Completed loading after \(time)")
        if error != nil {
            print("Error: \(error!.localizedDescription)")
        }
    }
}

/**
* Helper function to test a single step (executes `tilesPerStep` number of tile loads)
*/
func testStep(timer : NSTimer) {
    let tiles = Firebase(url: firebaseUrl).childByAppendingPath("/tiles_test")
    let data = timer.userInfo as! Dictionary<String, AnyObject>
    let x = data["x"] as! Int
    let expectation = data["ex"] as! XCTestExpectation
    var loading = 0
    print("Start loading \(x)")

    for (var y=0; y<tilesPerStep; y++) {
        loading++
        tiles.childByAppendingPath("\(x)x\(y)").observeSingleEventOfType(.Value, withBlock: { snapshot in
            loading--
            if loading == 0 {
                print("Done loading \(x)")
                self.stepsRemaining--
                if self.stepsRemaining == 0 {
                    expectation.fulfill()
                }
            }
        })
    }
}

2 , 3G 15 25 .

, .

+1

Source: https://habr.com/ru/post/1622497/


All Articles