存储的node.js的setTimeout在Redis的返回值(Storing the return

2019-07-30 05:50发布

我使用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