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

Posted

技术标签:

【中文标题】node.js 和 socket.io 与 facebook 好友聊天【英文标题】:node.js and socket.io chat with facebook friends 【发布时间】:2014-12-10 09:34:58 【问题描述】:

我正在开发聊天功能,Facebook 好友只能在此聊天。我正在使用 redis 所以保存关系:fb_user_id - user_socket_id。这就是我的实现的样子:

从 Facebook 交朋友; 从redis中选择我朋友的socket id,在我的node客户端创建本地friends-sockets列表; 连接到节点服务器。服务器将我的套接字 id 保存到 redis 并通知我所有的朋友新朋友登录(关于我); 我所有的朋友都在更新本地好友-sockets 列表; 当有人向服务器发送聊天消息时,该消息带有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】:

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

http://socket.io/docs/using-multiple-nodes/

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

【讨论】:

以上是关于node.js 和 socket.io 与 facebook 好友聊天的主要内容,如果未能解决你的问题,请参考以下文章

将 Socket.IO 与 Apache、Node.js、SSL 和 CloudFlare (HTTP 500) 一起使用

Node.js、多线程和 Socket.io

将简单的 Node.js 和 Socket.io 聊天应用程序与 Rails 应用程序连接起来(在 Heroku 上)

与 Node.js / Socket.io 服务器共享 Laravel 会话

带有 Node.js 的 Socket.io

redis pub/sub 与 node.js 中的 socket.io