user.isOnline fix

wont hit db on every user socket connect or user disconnect
v1.18.x
barisusakli 11 years ago
parent fe58ea55d4
commit b7ee875b12

@ -33,7 +33,8 @@ define('forum/account/profile', ['forum/account/header'], function(header) {
app.openChat($('.account-username').html(), theirid); app.openChat($('.account-username').html(), theirid);
}); });
socket.on('user.isOnline', handleUserOnline); socket.removeListener('event:user_status_change', onUserStatusChange);
socket.on('event:user_status_change', onUserStatusChange);
if (yourid !== theirid) { if (yourid !== theirid) {
socket.emit('user.increaseViewCount', theirid); socket.emit('user.increaseViewCount', theirid);
@ -66,11 +67,7 @@ define('forum/account/profile', ['forum/account/header'], function(header) {
return false; return false;
} }
function handleUserOnline(err, data) { function onUserStatusChange(data) {
if (err) {
return app.alertError(err.message);
}
var onlineStatus = $('.account-online-status'); var onlineStatus = $('.account-online-status');
if(parseInt(ajaxify.variables.get('theirid'), 10) !== parseInt(data.uid, 10)) { if(parseInt(ajaxify.variables.get('theirid'), 10) !== parseInt(data.uid, 10)) {

@ -125,6 +125,19 @@ define('forum/chats', ['string', 'sounds'], function(S, sounds) {
$('.chats-list li[data-uid="' + withUid + '"]').removeClass('typing'); $('.chats-list li[data-uid="' + withUid + '"]').removeClass('typing');
}); });
socket.on('event:user_status_change', function(data) {
var userEl = $('.chats-list li[data-uid="' + data.uid +'"]');
if (userEl.length) {
var statusEl = userEl.find('.status');
translator.translate('[[global:' + data.status + ']]', function(translated) {
statusEl.attr('class', 'fa fa-circle status ' + data.status)
.attr('title', translated)
.attr('data-original-title', translated);
});
}
});
}; };
Chats.resizeMainWindow = function() { Chats.resizeMainWindow = function() {

@ -39,16 +39,16 @@ define('forum/topic/browsing', function() {
} }
}; };
Browsing.onUserOnline = function(err, data) { Browsing.onUserStatusChange = function(data) {
updateOnlineIcon($('.username-field[data-username="' + data.username + '"]'), data); updateOnlineIcon($('.username-field[data-uid="' + data.uid + '"]'), data.status);
updateBrowsingUsers(data); updateBrowsingUsers(data);
}; };
function updateOnlineIcon(el, userData) { function updateOnlineIcon(el, status) {
translator.translate('[[global:' + userData.status + ']]', function(translated) { translator.translate('[[global:' + status + ']]', function(translated) {
el.siblings('i') el.siblings('i')
.attr('class', 'fa fa-circle status ' + userData.status) .attr('class', 'fa fa-circle status ' + status)
.attr('title', translated) .attr('title', translated)
.attr('data-original-title', translated); .attr('data-original-title', translated);
}); });
@ -57,10 +57,8 @@ define('forum/topic/browsing', function() {
function updateBrowsingUsers(data) { function updateBrowsingUsers(data) {
var activeEl = $('.thread_active_users'); var activeEl = $('.thread_active_users');
var user = activeEl.find('a[data-uid="'+ data.uid + '"]'); var user = activeEl.find('a[data-uid="'+ data.uid + '"]');
if (user.length && !data.online) { if (user.length && data.status === 'offline') {
user.parent().remove(); user.parent().remove();
} else if(!user.length && data.online && data.rooms.indexOf('topic_' + ajaxify.variables.get('topic_id')) !== -1) {
addUserIcon(user);
} }
} }

@ -1,7 +1,7 @@
'use strict'; 'use strict';
/* globals app, ajaxify, define, socket, translator */ /* globals app, ajaxify, define, socket, translator, templates */
define('forum/topic/events', ['forum/topic/browsing', 'forum/topic/postTools', 'forum/topic/threadTools'], function(browsing, postTools, threadTools) { define('forum/topic/events', ['forum/topic/browsing', 'forum/topic/postTools', 'forum/topic/threadTools'], function(browsing, postTools, threadTools) {
@ -11,7 +11,7 @@ define('forum/topic/events', ['forum/topic/browsing', 'forum/topic/postTools', '
'event:update_users_in_room': browsing.onUpdateUsersInRoom, 'event:update_users_in_room': browsing.onUpdateUsersInRoom,
'event:user_enter': browsing.onUserEnter, 'event:user_enter': browsing.onUserEnter,
'event:user_leave': browsing.onUserLeave, 'event:user_leave': browsing.onUserLeave,
'user.isOnline': browsing.onUserOnline, 'event:user_status_change': browsing.onUserStatusChange,
'event:voted': updatePostVotesAndUserReputation, 'event:voted': updatePostVotesAndUserReputation,
'event:favourited': updateFavouriteCount, 'event:favourited': updateFavouriteCount,

@ -22,10 +22,8 @@ define('forum/users', function() {
handleSearch(); handleSearch();
socket.removeListener('event:user_status_change', onUserStatusChange);
socket.removeListener('user.isOnline', onUserIsOnline); socket.on('event:user_status_change', onUserStatusChange);
socket.on('user.isOnline', onUserIsOnline);
$('#load-more-users-btn').on('click', loadMoreUsers); $('#load-more-users-btn').on('click', loadMoreUsers);
@ -154,38 +152,29 @@ define('forum/users', function() {
}); });
} }
function onUserIsOnline(err, data) { function onUserStatusChange(data) {
var section = getActiveSection(); var section = getActiveSection();
if((section.indexOf('online') === 0 || section.indexOf('users') === 0) && !loadingMoreUsers) { if((section.indexOf('online') === 0 || section.indexOf('users') === 0)) {
updateUser(data); updateUser(data);
} }
} }
function updateUser(data) { function updateUser(data) {
var usersContainer = $('#users-container'); if (data.status === 'offline') {
var userEl = usersContainer.find('li[data-uid="' + data.uid +'"]');
if (!data.online) {
userEl.remove();
return; return;
} }
var usersContainer = $('#users-container');
var userEl = usersContainer.find('li[data-uid="' + data.uid +'"]');
ajaxify.loadTemplate('users', function(usersTemplate) {
var html = templates.parse(templates.getBlock(usersTemplate, 'users'), {users: [data]});
translator.translate(html, function(translated) {
if (userEl.length) { if (userEl.length) {
userEl.replaceWith(translated); var statusEl = userEl.find('.status');
return; translator.translate('[[global:' + data.status + ']]', function(translated) {
} statusEl.attr('class', 'fa fa-circle status ' + data.status)
.attr('title', translated)
var anonBox = usersContainer.find('li.anon-user'); .attr('data-original-title', translated);
if (anonBox.length) {
$(translated).insertBefore(anonBox);
} else {
usersContainer.append(translated);
}
});
}); });
} }
}
function getActiveSection() { function getActiveSection() {
var url = window.location.href, var url = window.location.href,

@ -114,7 +114,7 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar,
modal.find('.user-typing').addClass('hide'); modal.find('.user-typing').addClass('hide');
}); });
socket.on('user.isOnline', function(err, data) { socket.on('event:user_status_change', function(data) {
updateStatus(data.status); updateStatus(data.status);
}); });
}; };
@ -140,8 +140,11 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar,
}; };
function checkStatus(chatModal) { function checkStatus(chatModal) {
socket.emit('user.isOnline', chatModal.attr('touid'), function(err, data) { socket.emit('user.checkStatus', chatModal.attr('touid'), function(err, status) {
updateStatus(data.status); if (err) {
return app.alertError(err.message);
}
updateStatus(status);
}); });
} }

@ -216,6 +216,8 @@ var db = require('./database'),
}; };
Messaging.getRecentChats = function(uid, start, end, callback) { Messaging.getRecentChats = function(uid, start, end, callback) {
var websockets = require('./socket.io');
db.getSortedSetRevRange('uid:' + uid + ':chats', start, end, function(err, uids) { db.getSortedSetRevRange('uid:' + uid + ':chats', start, end, function(err, uids) {
if (err) { if (err) {
return callback(err); return callback(err);
@ -226,20 +228,20 @@ var db = require('./database'),
return callback(err); return callback(err);
} }
user.isOnline(uids, function(err, users) { user.getMultipleUserFields(uids, ['uid', 'username', 'picture', 'status'] , function(err, users) {
if (err) { if (err) {
return callback(err); return callback(err);
} }
users = users.filter(function(user) {
return user && parseInt(user.uid, 10);
});
users.forEach(function(user, index) { users.forEach(function(user, index) {
if (user) { if (user) {
user.unread = unreadUids[index]; user.unread = unreadUids[index];
user.status = websockets.isUserOnline(user.uid) ? user.status : 'offline';
} }
}); });
users = users.filter(function(user) {
return !!user.uid;
});
callback(null, users); callback(null, users);
}); });
}); });

@ -12,7 +12,6 @@ var SocketIO = require('socket.io'),
db = require('../database'), db = require('../database'),
user = require('../user'), user = require('../user'),
socketUser = require('./user'),
topics = require('../topics'), topics = require('../topics'),
logger = require('../logger'), logger = require('../logger'),
meta = require('../meta'), meta = require('../meta'),
@ -59,9 +58,9 @@ function onMessage(msg) {
onlineUsersMap[msg.uid] -= 1; onlineUsersMap[msg.uid] -= 1;
onlineUsersMap[msg.uid] = Math.max(0, onlineUsersMap[msg.uid]); onlineUsersMap[msg.uid] = Math.max(0, onlineUsersMap[msg.uid]);
} }
var index = 0;
if (msg.uid && onlineUsersMap[msg.uid] === 0) { if (msg.uid && onlineUsersMap[msg.uid] === 0) {
var index = onlineUsers.indexOf(msg.uid); index = onlineUsers.indexOf(msg.uid);
if (index !== -1) { if (index !== -1) {
onlineUsers.splice(index, 1); onlineUsers.splice(index, 1);
} }
@ -162,7 +161,7 @@ Sockets.init = function(server) {
async.parallel({ async.parallel({
user: function(next) { user: function(next) {
user.getUserFields(uid, ['username', 'userslug', 'picture'], next); user.getUserFields(uid, ['username', 'userslug', 'picture', 'status'], next);
}, },
isAdmin: function(next) { isAdmin: function(next) {
user.isAdministrator(uid, next); user.isAdministrator(uid, next);
@ -180,9 +179,7 @@ Sockets.init = function(server) {
uid: uid uid: uid
}); });
socketUser.isOnline(socket, uid, function(err, data) { socket.broadcast.emit('event:user_status_change', {uid:uid, status: userData.user.status});
socket.broadcast.emit('user.isOnline', err, data);
});
}); });
}); });
} else { } else {
@ -200,9 +197,10 @@ Sockets.init = function(server) {
if (uid && (!onlineUsersMap[uid] || onlineUsersMap[uid] <= 1)) { if (uid && (!onlineUsersMap[uid] || onlineUsersMap[uid] <= 1)) {
db.sortedSetRemove('users:online', uid, function(err) { db.sortedSetRemove('users:online', uid, function(err) {
socketUser.isOnline(socket, uid, function(err, data) { if (err) {
socket.broadcast.emit('user.isOnline', err, data); return winston.error(err.message);
}); }
socket.broadcast.emit('event:user_status_change', {uid: uid, status: 'offline'});
}); });
} }
@ -295,7 +293,8 @@ Sockets.uidInRoom = function(uid, room) {
Sockets.getSocketCount = function() { Sockets.getSocketCount = function() {
return Object.keys(socketIdToUid).length; return Object.keys(socketIdToUid).length;
} };
Sockets.getConnectedClients = function() { Sockets.getConnectedClients = function() {
return onlineUsers; return onlineUsers;
}; };

@ -8,7 +8,8 @@ var async = require('async'),
notifications = require('../notifications'), notifications = require('../notifications'),
messaging = require('../messaging'), messaging = require('../messaging'),
plugins = require('../plugins'), plugins = require('../plugins'),
utils = require('./../../public/src/utils'), utils = require('../../public/src/utils'),
websockets = require('./index'),
meta = require('../meta'), meta = require('../meta'),
SocketUser = {}; SocketUser = {};
@ -87,13 +88,20 @@ SocketUser.reset.commit = function(socket, data, callback) {
} }
}; };
var tempCache = null; // temp, as always a false promise --psychobunny SocketUser.checkStatus = function(socket, uid, callback) {
SocketUser.isOnline = function(socket, uid, callback) { if (!socket.uid) {
if (tempCache) return callback(null, tempCache); return callback('[[error:invalid-uid]]');
}
user.isOnline([uid], function(err, data) { var online = websockets.isUserOnline(uid);
tempCache = Array.isArray(data) ? data[0] : null; if (!online) {
callback(err, tempCache); return callback(null, 'offline');
}
user.getUserField(uid, 'status', function(err, status) {
if (err) {
return callback(err);
}
status = status || 'online';
callback(null, status);
}); });
}; };
@ -321,12 +329,19 @@ SocketUser.loadMore = function(socket, data, callback) {
SocketUser.setStatus = function(socket, status, callback) { SocketUser.setStatus = function(socket, status, callback) {
var server = require('./index'); if (!socket.uid) {
return callback(new Error('[[invalid-uid]]'));
}
user.setUserField(socket.uid, 'status', status, function(err) { user.setUserField(socket.uid, 'status', status, function(err) {
SocketUser.isOnline(socket, socket.uid, function(err, data) { if (err) {
server.server.sockets.emit('user.isOnline', err, data); return callback(err);
callback(err, data); }
}); var data = {
uid: socket.uid,
status: status
};
websockets.server.sockets.emit('event:user_status_change', data);
callback(null, data);
}); });
}; };

@ -408,36 +408,6 @@ var
} }
}; };
User.isOnline = function(uids, callback) {
if (!Array.isArray(uids)) {
uids = [uids];
}
User.getMultipleUserFields(uids, ['uid', 'username', 'userslug', 'picture', 'status', 'reputation', 'postcount'] , function(err, userData) {
if (err) {
return callback(err);
}
var websockets = require('./socket.io');
userData = userData.map(function(user) {
var online = websockets.isUserOnline(user.uid);
user.status = online ? (user.status || 'online') : 'offline';
if (user.status === 'offline') {
online = false;
}
user.online = online;
user.timestamp = Date.now();
user.rooms = websockets.getUserRooms(user.uid);
return user;
});
callback(null, userData);
});
};
User.getIgnoredCategories = function(uid, callback) { User.getIgnoredCategories = function(uid, callback) {
db.getSortedSetRange('uid:' + uid + ':ignored:cids', 0, -1, callback); db.getSortedSetRange('uid:' + uid + ':ignored:cids', 0, -1, callback);
}; };

Loading…
Cancel
Save