我使用setTimeout
在Node.js的,它似乎来自客户端的行为不同setTimeout
,它返回一个对象,而不是数量。 我想这些信息存储在Redis的,但由于Redis的只存储字符串,我需要将对象转换为字符串。 然而,使用JSON.stringify
抛出循环引用错误。 我怎么能存储在Redis的这个对象,如果我希望能够从Redis的获取它,并调用clearTimeout
上呢?
Answer 1:
你不能存储在Redis的对象。 所述setTimeout
方法返回一个处理程序(对象引用)。
一个想法是在内存中创建自己的关联数组,并存储在Redis的索引。 例如:
var nextTimerIndex = 0;
var timerMap = {};
var timer = setTimeout(function(timerIndex) {
console.log('Ding!');
// Free timer reference!
delete timerMap[timerIndex];
}, 5 * 1000, nextTimerIndex);
// Store index in Redis...
// Then, store the timer object for later reference
timerMap[nextTimerIndex++] = timer;
// ...
// To clear the timeout
clearTimeout(timerMap[myTimerIndex]);
Answer 2:
我试图做同样的事情OP。 我的解决办法,设置超时时间与我的断开连接处理超时内一个新的关键条件检查:
redis.hset("userDisconnecting:" + userId, "disconnect", 1);
setTimeout(function() {
redis.hget("userDisconnecting:" + userId, "disconnect",
function(err, result) {
if (result.toString() === "1") {
//do stuff, like notify other clients of the disconnect.
}
});
}, 10000);
然后,当客户再次进行连接,我设置关键0
,因此需要对射击真正断开不会发生的东西:
redis.hset("userDisconnecting:" + userId, "disconnect", 0);
超时本身并不在服务器重新启动持久的,但你可以解决,通过踢了在启动时清扫方法。 连接的客户端会回来的“在线”很快。
Answer 3:
当超时不需要在服务器重新启动持续此代码用于
var timeouts = {};
app.get('/', function (req, res) {
var index = timeouts.length;
timeouts[index] = setTimeout(console.log, 1000000, req.user.name);
redis.set('timeout:' + req.user.name, index, function (err, reply) {
res.end();
});
});
app.get('/clear', function (req, res) {
redis.get('timeout:' + req.user.name, function (err, index) {
clearTimeout(timeouts[index]);
delete timeouts[index];
redis.delete('timeout:' + req.user.name);
res.end();
});
});
如果你需要超时是在服务器重新启动持久的,那么你可能需要存储_idleStart
和_idleTimeout
值在Redis的每一个计时器,并装载它们每次你重新启动服务器
app.get('/', function (req, res) {
var timeout = setTimeout(console.log, 1000000, req.user.name);
var time = timeout._idleStart.getTime() + timeout._idleTimeout;
redis.set('timeout:' + req.user.name, time, function (err, reply) {
res.end();
});
});
app.get('/clear', function (req, res) {
redis.delete('timeout:' + req.user.name);
res.end();
});
// Load timeouts on server start
// *I know this is not the correct redis command*
// *It's not accurate, only approx*
redis.get('timeout:*', function (err, vals) {
vals.forEach(function (val) {
var time = val - new Date().getTime();
setTimeout(console.log, time, username)
});
});
文章来源: Storing the return value of node.js setTimeout in redis