不要在Firebase页面刷新时调用onDisconnect()

时间:2016-10-12 10:36:23

标签: javascript firebase firebase-realtime-database

我已使用此代码更新当前登录用户的在线/离线状态,其中z是用户ID。

var ref = firebase.database().ref("users/"+z);
    ref.update({
       online: "1"
    });
    ref.onDisconnect().update({
      online: "0"
    });

我创建了另一个参考,用于检查用户是否在线离线/在线。这里oid是其他用户的用户ID。

db = firebase.database().ref().child("users/"+oid);
       db.on('value', function(snapShot){
          var data = snapShot.val();
          if(data.online === "0")
          {
              var lastvisible = getTime(data.lastvisibleat);
              var div = $("[data-conli-id="+cid+"]");
              if(div.hasClass('online'))
              {
                  div.removeClass('online');
                  div.addClass('offline');
                  div.find("#user-status-li").attr("data-lv", lastvisible);
              }
              else if(div.hasClass('offline'))
              {
                  div.find("#user-status-li").attr("data-lv", lastvisible);
              }
              var chat_box_div = $("#chat-box-"+cid);
              if(chat_box_div)
              {
                  var user_status_div = chat_box_div.find("#user-status");
                  if(user_status_div.text() === 'online')
                  {
                     user_status_div.text('offline');

                     user_status_div.text(lastvisible+" ago");
                  }
              }
          }
          else if(data.online === "1")
          {
              var div = $("[data-conli-id="+cid+"]");
              if(div.hasClass('offline'))
              {
                  div.removeClass('offline');
                  div.addClass('online');
              }
              var chat_box_div = $("#chat-box-"+cid);
              if(chat_box_div)
              {
                  var user_status_div = chat_box_div.find("#user-status");
                  if(user_status_div.text() === 'offline' || user_status_div.text() !== 'online')
                  {
                     user_status_div.text('online');
                  }
              }
          }
       });

这对我来说很好。如果浏览器崩溃或互联网消失或用户退出。问题是当用户刷新当前页面或导航到另一页时。

这个JS文件中的代码被重新加载,并且用户在另一端看到用户离线,尽管他刚刚刷新了它。

在没有CRON工作的情况下,是否有onDisconnect()的解决方法?

3 个答案:

答案 0 :(得分:1)

由于onDisconnect()是服务器端操作,并且每次卸载页面时都会切断与服务器的连接,因此这里的简单答案是否定的:您不能阻止onDisconnect()在触发时触发客户端已断开连接。

您可以做的是延迟对onDisconnect()事件的响应,并查看它是否在合理的阈值(例如10秒)内重新连接。如果没有,则可以将用户显示为离线。

更优雅的应用程序设计的第二种选择是利用a routing tool并将您的代码转换为单页应用程序,其中连接不必被切断以显示新内容。

答案 1 :(得分:0)

使用setInterval()每2分钟更新一次Firebase中的值。然后使用CRON作业检查游戏中时光倒流并相应地将用户设置为脱机状态。

setInterval(function() {
   var ref = firebase.database().ref("users/"+z);
   var d = new Date().today();
   ref.update({
      lastactivityat: d
   });
}, 120000);

在服务器上使用CRON PHP脚本。在这里,我从MySQL数据库表中获取$userid

$user_data = $firebase->get('/users/'.$userid."/lastactivityat");
$user = json_decode($user_data, true);
if(count($user) != 0)
{
    $currentDate = date('Y-m-d H:i:s');
    $userLastActivity = date($user);
    $timeLapse = ($currentDate - $userLastActivity)/60;
    if($timeLapse > 5)
    {
        $firebase->set('/users/'.$userid.'/lastvisibleat', date('Y-m-d H:i:s'));
        $firebase->set('/users/'.$userid.'/online', '0');
    }
}

使用合适的服务器配置,这可以完美有效地工作。

答案 2 :(得分:0)

我遇到了同样的问题,并尝试了@ prashant0205的回答。但是运行CRON并持续调用firebase似乎不是一个合适的解决方案。 我试过的是在相反的一侧延迟更新UI。也就是说,如果用户A 刷新页面并使用onDisconnect()方法脱机,我就不会在处更改用户A 的状态用户B 的立即。在延迟10秒后,我再次呼叫用户节点,如果它仍然是0,那么我会让他/她离线。

注意:我在延迟方法中使用了once来避免多次绑定!

/*Listen user's firebase node*/
function listenUser (user_id) {
	var dbUserRefObj = firebase.database().ref().child("USERS/"+user_id);
    var recentUserData = '';

    dbUserRefObj.on("value",function(snapshotUser){
        if(snapshotUser.exists() == true){
            recentUserData = snapshotUser.val();

            if(typeof recentUserData.status != 'undefined' && recentUserData.status == 1){
                //Online
            }else{
                /*Put delay before showing offline*/
               
                offlineDelay (user_id)
            }

        }else{
            //offline
        }
    });
}

/*Firebase offline delay function*/
function offlineDelay (user_id) {
	/*If user status does not changes in 10 seconds, mark as offline*/
	setTimeout(function () {
		var dbUserRefObj = firebase.database().ref().child("USERS/"+user_id);
	    var recentUserData = '';

	    dbUserRefObj.once("value",function(snapshotUser){
	        if(snapshotUser.exists() == true){
	            recentUserData = snapshotUser.val();

	            if(typeof recentUserData.status != 'undefined' && recentUserData.status == 1){
	                //online
	            }else{
	                //offline
	            }

	        }else{
	            //offline
	        }
	    });
	},10000);
}