我已使用此代码更新当前登录用户的在线/离线状态,其中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()
的解决方法?
答案 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);
}