跨多个客户端同步的Firebase队列计时器,无论客户端断开/连接如何

时间:2018-11-02 18:23:04

标签: javascript firebase-realtime-database setinterval

我已经为Firebase创建了一个计时器,但是当用户断开连接时,它无法正常工作。

问题:

计时器用于排队,因此所有用户都需要能够看到直到下一个人的当前时间。目前,我拥有这样的功能,即当用户单击队列按钮时,他们的客户端会减少剩余时间,使用Firebase方法.set()设置Firebase中的剩余时间,然后将Firebase值显示给所有用户。

此功能有效, 除外,当单击按钮的用户在计时器完成之前退出时,因为这将导致计时器停止递减。从功能上讲,我的目标是允许用户离开页面并返回,因此我想我可以在断开连接时重置计时器,但理想情况下,我希望计时器继续运行。

方法/想法:

我不确定该如何处理。我在考虑让客户端处理自己的计时器,有点像this answer,部分原因是有人提到使用interval()并不是计时器的最准确方法,但是我必须找到一种方法来允许之后输入的用户接收更新的时间。我可以通过让所有用户.set()设置Firebase时间来描述这一点,以便该页面的新用户可以看到剩余的更新时间,但是要让所有用户同时更新相同的数据似乎非常糟糕。我只是最近才开始研究交易,但是它们似乎很有希望,因为它们似乎能够处理许多用户试图更新相同值的情况,但是即使那样,我仍不确定这是最好的方法。我还考虑过拥有一种永远不会注销并管理所有用户时间的“主”客户端。

无论如何,下面是我的代码。我尝试仅包含相关代码,所以如果有任何不清楚的地方,请告诉我:

var database = firebase.database();
//firebase queue
var queueDB = firebase.database().ref().child("queue");
//get first person
varquery = firebase.database().ref("queue").orderByKey().limitToFirst(1);
let peopleInQueue;
//timer
var timerDB = firebase.database().ref().child("seconds");
let seconds_left = 100;
var timerState = firebase.database().ref("timerState");
let timer;

timerState.on("value", function(snapshot) {
    timer= snapshot.val();
 });

document.getElementById("queue").onclick = function() {

    if (timer == "on") {
       //prevent timer from decrementing more if already on
       return;
      }

    timerState.set('on'); 

    function setTimer() {

      let interval = setInterval(function() {
        if (timer == "on") {
          //clident side
          --seconds_left;
          //sets Firebase time left value based on client time left value
          timerDB.set(seconds_left);
          }

        if (seconds_left <= 0) {
        //query to find first person in queue and remove them  
        query.once("value")
          .then(function(snapshot) {
              snapshot.forEach(function(childSnapshot) {

              //key returns all the children nodes
              let key = childSnapshot.key;
             //reomve first person from queue
             childSnapshot.ref.remove();
               });
            });
        document.getElementById("timer_div").innerHTML = "You are Ready!";
        clearInterval(interval);
        seconds_left = 100;
        timerDB.set(seconds_left);

        //check to see if queue is done, if not repeat timer
        if (peopleInQueue >= 2) {
          setTimer();
         } 
        else {
         timerState.set('off');
        }
      }
    }, 1000);
  }
};

0 个答案:

没有答案