1

我正在使用带有 Redis 的 Socket.IO 和负载平衡实例构建一个用于实时流式传输的存在系统。每次用户进入房间时,我都会向服务器发送 socket.emit('join', roomId) 并且服务器将用户加入相应的房间。每分钟,我都会刷新仪表板,并使用这样的 redis 适配器让所有用户连接到实例:

io.of('/').adapter.clients([req.params.name], (err, clients) => {
        console.log(clients.length); // an array containing all connected socket ids
        if (req.query.detail) {
            res.send(clients);
        } else {
            res.send({onlineUsers: clients.length});
        }
    });

如果我的一台服务器出现故障,Redis 会自动删除所有连接的套接字,并几乎立即刷新该房间中的套接字数量。

现在的问题:每当用户连接时,我都会打电话

io.of('/').on('connection', function (socket) {
    //.. set user Online in database
});

用于设置用户在线。

当用户断开连接时,我会

io.of('/').on('disconnect', function (socket) {
    //... Set user offline
});

问题是……如果我的服务器出现了一段时间的宕机,用户将永远被标记为在线。看到我有超过 20,000 人在线,几乎不可能每分钟向服务器发送一个使用 LastSeen 更新数据库的请求,因为这会导致超过 300 次写入/秒(我认为 mongodb 不会处理,会它 ?)

有什么方法可以解决这个问题吗?使用redis存储一些数据,以防服务器离线一段时间,我恢复上一个状态?怎么会这样?

有什么解决方案吗?即使socketio重试重连,如果服务器离线1分钟,用户离开,他将永远在线。

谢谢你 !

4

0 回答 0