【发布时间】: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);
}
});
}
【问题讨论】:
标签: node.js facebook redis socket.io high-availability