From b7ee875b12f59b4fd6c40eba4503a327f55ea9bc Mon Sep 17 00:00:00 2001 From: barisusakli Date: Sat, 6 Sep 2014 22:08:55 -0400 Subject: [PATCH] user.isOnline fix wont hit db on every user socket connect or user disconnect --- public/src/forum/account/profile.js | 9 +++---- public/src/forum/chats.js | 13 +++++++++ public/src/forum/topic/browsing.js | 14 +++++----- public/src/forum/topic/events.js | 4 +-- public/src/forum/users.js | 39 ++++++++++----------------- public/src/modules/chat.js | 9 ++++--- src/messaging.js | 14 +++++----- src/socket.io/index.js | 21 +++++++-------- src/socket.io/user.js | 41 ++++++++++++++++++++--------- src/user.js | 30 --------------------- 10 files changed, 90 insertions(+), 104 deletions(-) diff --git a/public/src/forum/account/profile.js b/public/src/forum/account/profile.js index a9633b6aba..a7a522f220 100644 --- a/public/src/forum/account/profile.js +++ b/public/src/forum/account/profile.js @@ -33,7 +33,8 @@ define('forum/account/profile', ['forum/account/header'], function(header) { 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) { socket.emit('user.increaseViewCount', theirid); @@ -66,11 +67,7 @@ define('forum/account/profile', ['forum/account/header'], function(header) { return false; } - function handleUserOnline(err, data) { - if (err) { - return app.alertError(err.message); - } - + function onUserStatusChange(data) { var onlineStatus = $('.account-online-status'); if(parseInt(ajaxify.variables.get('theirid'), 10) !== parseInt(data.uid, 10)) { diff --git a/public/src/forum/chats.js b/public/src/forum/chats.js index 5ad1bd6229..2d2123b5d3 100644 --- a/public/src/forum/chats.js +++ b/public/src/forum/chats.js @@ -125,6 +125,19 @@ define('forum/chats', ['string', 'sounds'], function(S, sounds) { $('.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() { diff --git a/public/src/forum/topic/browsing.js b/public/src/forum/topic/browsing.js index 80929bf454..d2cebbcf14 100644 --- a/public/src/forum/topic/browsing.js +++ b/public/src/forum/topic/browsing.js @@ -39,16 +39,16 @@ define('forum/topic/browsing', function() { } }; - Browsing.onUserOnline = function(err, data) { - updateOnlineIcon($('.username-field[data-username="' + data.username + '"]'), data); + Browsing.onUserStatusChange = function(data) { + updateOnlineIcon($('.username-field[data-uid="' + data.uid + '"]'), data.status); updateBrowsingUsers(data); }; - function updateOnlineIcon(el, userData) { - translator.translate('[[global:' + userData.status + ']]', function(translated) { + function updateOnlineIcon(el, status) { + translator.translate('[[global:' + status + ']]', function(translated) { el.siblings('i') - .attr('class', 'fa fa-circle status ' + userData.status) + .attr('class', 'fa fa-circle status ' + status) .attr('title', translated) .attr('data-original-title', translated); }); @@ -57,10 +57,8 @@ define('forum/topic/browsing', function() { function updateBrowsingUsers(data) { var activeEl = $('.thread_active_users'); var user = activeEl.find('a[data-uid="'+ data.uid + '"]'); - if (user.length && !data.online) { + if (user.length && data.status === 'offline') { user.parent().remove(); - } else if(!user.length && data.online && data.rooms.indexOf('topic_' + ajaxify.variables.get('topic_id')) !== -1) { - addUserIcon(user); } } diff --git a/public/src/forum/topic/events.js b/public/src/forum/topic/events.js index a84d7ad1d6..ec61a8ff0e 100644 --- a/public/src/forum/topic/events.js +++ b/public/src/forum/topic/events.js @@ -1,7 +1,7 @@ '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) { @@ -11,7 +11,7 @@ define('forum/topic/events', ['forum/topic/browsing', 'forum/topic/postTools', ' 'event:update_users_in_room': browsing.onUpdateUsersInRoom, 'event:user_enter': browsing.onUserEnter, 'event:user_leave': browsing.onUserLeave, - 'user.isOnline': browsing.onUserOnline, + 'event:user_status_change': browsing.onUserStatusChange, 'event:voted': updatePostVotesAndUserReputation, 'event:favourited': updateFavouriteCount, diff --git a/public/src/forum/users.js b/public/src/forum/users.js index cdf1ab9e73..77a56c7b51 100644 --- a/public/src/forum/users.js +++ b/public/src/forum/users.js @@ -22,10 +22,8 @@ define('forum/users', function() { handleSearch(); - - socket.removeListener('user.isOnline', onUserIsOnline); - socket.on('user.isOnline', onUserIsOnline); - + socket.removeListener('event:user_status_change', onUserStatusChange); + socket.on('event:user_status_change', onUserStatusChange); $('#load-more-users-btn').on('click', loadMoreUsers); @@ -154,37 +152,28 @@ define('forum/users', function() { }); } - function onUserIsOnline(err, data) { + function onUserStatusChange(data) { var section = getActiveSection(); - if((section.indexOf('online') === 0 || section.indexOf('users') === 0) && !loadingMoreUsers) { + if((section.indexOf('online') === 0 || section.indexOf('users') === 0)) { updateUser(data); } } function updateUser(data) { - var usersContainer = $('#users-container'); - var userEl = usersContainer.find('li[data-uid="' + data.uid +'"]'); - if (!data.online) { - userEl.remove(); + if (data.status === 'offline') { 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) { - userEl.replaceWith(translated); - return; - } - - var anonBox = usersContainer.find('li.anon-user'); - if (anonBox.length) { - $(translated).insertBefore(anonBox); - } else { - usersContainer.append(translated); - } + 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); }); - }); + } } function getActiveSection() { diff --git a/public/src/modules/chat.js b/public/src/modules/chat.js index 62221d8cc1..b4234bd488 100644 --- a/public/src/modules/chat.js +++ b/public/src/modules/chat.js @@ -114,7 +114,7 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, modal.find('.user-typing').addClass('hide'); }); - socket.on('user.isOnline', function(err, data) { + socket.on('event:user_status_change', function(data) { updateStatus(data.status); }); }; @@ -140,8 +140,11 @@ define('chat', ['taskbar', 'string', 'sounds', 'forum/chats'], function(taskbar, }; function checkStatus(chatModal) { - socket.emit('user.isOnline', chatModal.attr('touid'), function(err, data) { - updateStatus(data.status); + socket.emit('user.checkStatus', chatModal.attr('touid'), function(err, status) { + if (err) { + return app.alertError(err.message); + } + updateStatus(status); }); } diff --git a/src/messaging.js b/src/messaging.js index d6cd44be5a..d951b4a3ea 100644 --- a/src/messaging.js +++ b/src/messaging.js @@ -216,8 +216,10 @@ var db = require('./database'), }; Messaging.getRecentChats = function(uid, start, end, callback) { + var websockets = require('./socket.io'); + db.getSortedSetRevRange('uid:' + uid + ':chats', start, end, function(err, uids) { - if(err) { + if (err) { return callback(err); } @@ -226,20 +228,20 @@ var db = require('./database'), return callback(err); } - user.isOnline(uids, function(err, users) { + user.getMultipleUserFields(uids, ['uid', 'username', 'picture', 'status'] , function(err, users) { if (err) { return callback(err); } - + users = users.filter(function(user) { + return user && parseInt(user.uid, 10); + }); users.forEach(function(user, index) { if (user) { user.unread = unreadUids[index]; + user.status = websockets.isUserOnline(user.uid) ? user.status : 'offline'; } }); - users = users.filter(function(user) { - return !!user.uid; - }); callback(null, users); }); }); diff --git a/src/socket.io/index.js b/src/socket.io/index.js index 2192e9fd06..f768901834 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -12,7 +12,6 @@ var SocketIO = require('socket.io'), db = require('../database'), user = require('../user'), - socketUser = require('./user'), topics = require('../topics'), logger = require('../logger'), meta = require('../meta'), @@ -59,9 +58,9 @@ function onMessage(msg) { onlineUsersMap[msg.uid] -= 1; onlineUsersMap[msg.uid] = Math.max(0, onlineUsersMap[msg.uid]); } - + var index = 0; if (msg.uid && onlineUsersMap[msg.uid] === 0) { - var index = onlineUsers.indexOf(msg.uid); + index = onlineUsers.indexOf(msg.uid); if (index !== -1) { onlineUsers.splice(index, 1); } @@ -162,7 +161,7 @@ Sockets.init = function(server) { async.parallel({ user: function(next) { - user.getUserFields(uid, ['username', 'userslug', 'picture'], next); + user.getUserFields(uid, ['username', 'userslug', 'picture', 'status'], next); }, isAdmin: function(next) { user.isAdministrator(uid, next); @@ -180,9 +179,7 @@ Sockets.init = function(server) { uid: uid }); - socketUser.isOnline(socket, uid, function(err, data) { - socket.broadcast.emit('user.isOnline', err, data); - }); + socket.broadcast.emit('event:user_status_change', {uid:uid, status: userData.user.status}); }); }); } else { @@ -200,9 +197,10 @@ Sockets.init = function(server) { if (uid && (!onlineUsersMap[uid] || onlineUsersMap[uid] <= 1)) { db.sortedSetRemove('users:online', uid, function(err) { - socketUser.isOnline(socket, uid, function(err, data) { - socket.broadcast.emit('user.isOnline', err, data); - }); + if (err) { + 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() { return Object.keys(socketIdToUid).length; -} +}; + Sockets.getConnectedClients = function() { return onlineUsers; }; diff --git a/src/socket.io/user.js b/src/socket.io/user.js index 48cc87bd4b..538edac1d9 100644 --- a/src/socket.io/user.js +++ b/src/socket.io/user.js @@ -8,7 +8,8 @@ var async = require('async'), notifications = require('../notifications'), messaging = require('../messaging'), plugins = require('../plugins'), - utils = require('./../../public/src/utils'), + utils = require('../../public/src/utils'), + websockets = require('./index'), meta = require('../meta'), SocketUser = {}; @@ -87,13 +88,20 @@ SocketUser.reset.commit = function(socket, data, callback) { } }; -var tempCache = null; // temp, as always a false promise --psychobunny -SocketUser.isOnline = function(socket, uid, callback) { - if (tempCache) return callback(null, tempCache); - - user.isOnline([uid], function(err, data) { - tempCache = Array.isArray(data) ? data[0] : null; - callback(err, tempCache); +SocketUser.checkStatus = function(socket, uid, callback) { + if (!socket.uid) { + return callback('[[error:invalid-uid]]'); + } + var online = websockets.isUserOnline(uid); + if (!online) { + 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) { - var server = require('./index'); + if (!socket.uid) { + return callback(new Error('[[invalid-uid]]')); + } user.setUserField(socket.uid, 'status', status, function(err) { - SocketUser.isOnline(socket, socket.uid, function(err, data) { - server.server.sockets.emit('user.isOnline', err, data); - callback(err, data); - }); + if (err) { + return callback(err); + } + var data = { + uid: socket.uid, + status: status + }; + websockets.server.sockets.emit('event:user_status_change', data); + callback(null, data); }); }; diff --git a/src/user.js b/src/user.js index 67a8c81c4d..2de6ac0778 100644 --- a/src/user.js +++ b/src/user.js @@ -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) { db.getSortedSetRange('uid:' + uid + ':ignored:cids', 0, -1, callback); };