Показать сообщение отдельно
Старый 29.10.2015, 18:07   #28
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,863 пользователей)
Ответ: Чат: PHP + MySQLi или что то другое?

Данные о сокетах, хранить нужно только в ОЗУ node.js сервера. Бд об этом знать не нужно вообще.

Вот я написал пример кода, как хранить в ОЗУ список пользователей, их списки соединений и кэш друзей и т.п.
Твоя задача следить за кешем, чтобы он был всегда обновлен. Когда делаешь обновления через API добавляя/убирая там друзей, важно держать кеш обновленным тоже.

По сути users кеш - это все пользователи онлайн.
т.к. они хранятся по ключу, то проверка на онлайн и доступ к ним очень быстрый.

Вот код, думаю идея понятна.
// users cache object
var users = { };
// users load requests queue
var userRequests = { };


// user class
function User(data) {
    
this.id data.id;
    
this.name data.name;
    
this.friends data.friend_ids;
    
this.sockets = { };
    
this.connections 0;
}

// send message to all user connections
User.prototype.send = function(namedata) {
    for(var 
key in this.sockets)
        
this.sockets[key].emit(namedata);
};

// add user connection
User.prototype.socketAdd = function(socket) {
    if (
this.sockets[socket.id])
        return 
false;

    
this.sockets[socket.id] = socket;
    
this.connections++;

    return 
true;
};

// remove user connection
User.prototype.socketRemove = function(socket) {
    if (! 
this.sockets[socket.id])
        return 
false;

    
delete this.sockets[socket.id];
    
this.connections--;

    return 
true;
};


// try get or load user
var userGetOrLoad = function(idfn) {
    if (
users[id])
        return 
fn(nullusers[id]);

    
// loading in progress, just queue then
    
if (userRequests[id])
        return 
userRequests[id].push(fn);

    
// first one to try loading
    
userRequests[id] = [ fn ];

    
// once loaded, report to all who need this info
    
var finish = function(erruser) {
        for(var 
0userRequests[id].lengthi++)
            
userRequests[id](erruser);

        
delete userRequests[id];
    };

    
// try load user from db
    
db.collection('users').findOne({
        
_idid
    
}, {
        
fields: {
            
name1,
            
friend_ids1
        
}
    }, function(
erritem) {
        var 
user null;

        
// if user loaded, create cache
        
if (! err && item)
            
user users[id] = new User(item);

        
finish(erruser);
    });
};

// add client to user
var addClient = function(userIdsocket) {
    
userGetOrLoad(userId, function(erruser) {
        if (
err || ! user)
            return;

        var 
added user.socketAdd(socket);

        if (
added) {
            
// notify all friends about user being online
            
for(var 0user.friends.lengthi++) {
                var 
friend users[user.friends[i]];
                if (! 
friend) continue;
                
friend.send('friend:online', { iduser.id });
            }
        }
    });
};

// remove client from user
var removeClient = function(userIdsocket) {
    var 
user users[userId];

    if (! 
user)
        return;

    
user.socketRemove(socket);

    if (
user.connections === 0) {
        
delete users[userId];

        
// notify all friends that user is offline now
        
for(var 0user.friends.lengthi++) {
            var 
friend users[user.friends[i]];
            if (! 
friend) continue;
            
friend.send('friend:offline', { iduser.id });
        }
    }
}; 
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
St_AnGer (29.10.2015)