node.js和socket.io与facebook好友聊天

时间:2014-12-10 09:34:59

标签: node.js facebook redis socket.io high-availability

我正在聊天,Facebook的朋友可以互相交谈。我正在使用redis所以保存关系:fb_user_id - user_socket_id。这就是我的实现方式:

  • 从facebook获取朋友;
  • 从redis中选择朋友的socket id,在我的节点客户端中创建本地的friends-socket列表;
  • 连接到节点服务器。服务器将我的套接字ID保存到redis并通知我的所有朋友关于新朋友登录(关于我);
  • 我所有的朋友都在更新本地的朋友套接字列表;
  • 当有人向服务器发送聊天消息时,此消息附带了friends-sockets列表,因此服务器知道需要发送消息的位置(仅适用于我的朋友)。

问题:每次向服务器发送friends-sockets是更好的解决方案,或者最好从redis(或在服务器中创建套接字阵列)在服务器上获取此关系。如何调整我的任务以实现高可用性?

欢迎任何意见和建议,谢谢。

这是我的代码(socket.io 1.2.0)

server.js

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

var redis = require("redis"), client = redis.createClient();
var parts;
client.select(2, function() {});
client.on("error", function (err) {
    console.log("Error " + err);
});

process.on('uncaughtException', function (err) {
    console.log(err);
});

app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html');
});

io.on('connection', function (socket) {

    // on connect
    socket.on("join", function (data)
    {
        if (data) {
            // notify all friedns about new friend login
            if (data.to) {
                if (data.to.length > 0) {
                    for (x in data.to) {
                        io.to(data.to[x]['socket_id']).emit('new friend response', {uid: data.uid, sid: socket.id});
                    }
                }
            }

            // save or update user socket id to redis
            parts = split_id(data.uid);
            client.hset(parts[1], parts[0], socket.id);

        }
    });

    // disconnect
    socket.on('disconnect', function () {
        console.log("user disconnected");
    });

    // send message by friends-sockets list
    socket.on('chat message', function (data) {
        if (data.to.length > 0) {
            for (x in data.to) {
                var message = data.msg;
                io.to(data.to[x]['socket_id']).emit('chat message response', {msg: message, uid: data.uid});
            }
        }
    });
});

http.listen(3000, function () {
    console.log('listening on *:3000');
});

// split facebook uid in 2 parts (for redis saving)
function split_id(str)
{
    var n = str.length;
    var res1 = str.substr(n - 2, 2);
    var res2 = str.substr(0, n - 2);
    return [res1, res2];
}

client.js

// friends socket list
var friends_sockets = [];
// my data from facebook
var my_data;
// my facebook uid
var my_uid;

function client() {
    socket = io('http://server.com:3000');

    // connect
    socket.on('connect', function () {
        // notify server about login
        socket.emit('join', {uid: my_uid, to: friends_sockets, from: my_data, type: 'web'});
    });

    // send chat message to my friends
    $('.enter_form button').click(function () {
        if (friends_sockets.length > 0) {
            socket.emit('chat message', {msg: $('#m').val(), to: friends_sockets, from: my_data, uid: my_uid});
        }
        // add message to my chat
        $('#messages').append($('<li>').text(my_data.first_name + ' ' + my_data.last_name + ': ' + $('#m').val()));
        $('#m').val('');
        return false;
    });

    // new message listner (waiting for chat messages)
    socket.on('chat message response', function (data) {
        $('#messages').append($('<li>').text(data.msg));
    });

    // new friends lister (update list on friends login)
    socket.on('new friend response', function (data) {
        var found = false;
        if (friends_sockets.length > 0) {
            for (x in friends_sockets) {
                if (friends_sockets[x]['uid'] == data.uid) {
                    friends_sockets[x]['socket_id'] = data.sid;
                    found = true;
                }
            }
        }

        if (found === false) {
            friends_sockets.push(data);
        }
    });
}

1 个答案:

答案 0 :(得分:0)

关于您的高可用性问题,请查看

使用nginx,多个Node进程和Redis作为会话存储的配置示例。