我最近刚刚搭建了一个聊天室,它运行得很好,但我认为我需要将其连接到redis。
据我所知,如果客户端刷新或服务器崩溃,我需要redis来进行扩展和保持一些数据。
1对1聊天的核心组成部分是存储用户,并将socket.id
与这些用户关联起来。
var users = {};
io.sockets.on('connection', function (socket) {
// store the users & socket.id into objects
users[socket.handshake.headers.user.username] = socket.id;
});
现在,在客户端上,只要输入的是有效用户"Jack",我就可以通过向服务器传递数据来与之聊天,即用户名和消息只会发送给Jack。
var chattingWith = data.nickname; // this is Jack passed from the client side
io.to(users[chattingWith]).emit();
我的问题是,为什么应该使用redis?在redis中应该存储什么?如何与数据进行交互?我正在使用一个io.adapter。io.adapter(redisIo({
host: 'localhost',
port: 6379,
pubClient: pub,
subClient: sub
}));
同时,从示例应用程序中阅读代码时,我发现当套接字连接时,它们会将套接字数据保存到Redis中,如下所示。
// store stuff in redis
redisClientPublish.sadd('sockets:for:' + userKey + ':at:' + room_id, socket.id, function(err, socketAdded) {
if(socketAdded) {
redisClientPublish.sadd('socketio:sockets', socket.id);
redisClientPublish.sadd('rooms:' + room_id + ':online', userKey, function(err, userAdded) {
if(userAdded) {
redisClientPublish.hincrby('rooms:' + room_id + ':info', 'online', 1);
redisClientPublish.get('users:' + userKey + ':status', function(err, status) {
io.sockets.in(room_id).emit('new user', {
nickname: nickname,
provider: provider,
status: status || 'available'
});
});
}
});
}
});
他们在进入一个房间时使用它,以获取有关该房间的信息。
app.get('/:id', utils.restrict, function(req, res) {
console.log(redisClientPublish);
utils.getRoomInfo(req, res, redisClientPublish, function(room) {
console.log('Room Info: ' + room);
utils.getUsersInRoom(req, res, redisClientPublish, room, function(users) {
utils.getPublicRoomsInfo(redisClientPublish, function(rooms) {
utils.getUserStatus(req.user, redisClientPublish, function(status) {
utils.enterRoom(req, res, room, users, rooms, status);
});
});
});
});
});
因此,我之所以问这个问题,是因为我有些困惑是否需要在redis中存储任何东西/为什么需要这样做,例如,我们可能有几十万个用户,并且正在聊天的node.js服务器“Jack”和“Mike”出现故障,然后它会更改为指向新的node.js实例。
显然,我希望聊天仍然记得“Jack”的套接字ID是“12333”和“Mike”的套接字ID是“09278”,因此无论何时,“Jack”说嘿,我要发送消息给“Mike/09278”,服务器端套接字都将正确地将其定向。
将用户名存储为键,套接字ID作为值,对于redis来说是明智的使用情况吗?那个socket.id还有效吗?