Делайте с помощью массива. Допустим, вы при соединении к socket.io получаете user id.
Записывайте его в объект.
var clients = {}; // global variable node
... соединение {
('u' + user_id in clients ? client['u' + user_id] : clients['u' + user_id] = []).push(socket.id);
... }
В итоге при открытии двух вкладок у вас будет массив:
{
'u1': [socket_id_hash_one, socket_id_hash_two]
}
И уже при выполнении каких-либо emit у вас будет список socket_id определенного пользователя для которых совершать emit.
Как совершить emit определенному клиенту?io.sockets.connected[socket_id].emit('data', {data: 123}));
Что делать если пользователь закрыл вкладку?var clients = {}; // global variable node
... соединение {
('u' + user_id in clients ? client['u' + user_id] : clients['u' + user_id] = []).push(socket.id);
... }
...
setInterval(function () {
// io.eio.clientsCount — количество подключенных клиентов
// io.eio.clients — список socket_id подключенных клиентов
// на основании пишем цикл, который изменяет объект clients в зависимости от io.eio.clients
// на этом основании можно сделать user online list
}, 500);