mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-29 18:16:17 +01:00
user.isOnline fix
wont hit db on every user socket connect or user disconnect
This commit is contained in:
@@ -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)) {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -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,38 +152,29 @@ 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) {
|
||||
if (data.status === 'offline') {
|
||||
return;
|
||||
}
|
||||
var usersContainer = $('#users-container');
|
||||
var userEl = usersContainer.find('li[data-uid="' + data.uid +'"]');
|
||||
if (!data.online) {
|
||||
userEl.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
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() {
|
||||
var url = window.location.href,
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -216,6 +216,8 @@ 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) {
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
30
src/user.js
30
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);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user