在套接字IO&中轮询MySQL数据库节点JS

时间:2015-11-17 22:45:06

标签: javascript mysql node.js socket.io

我试图通过每2秒迭代一次来检查MySQL数据库并检索在2秒前创建的所有记录。

如果我使用setInterval,它似乎偶尔会错过一条记录。如果我使用setTimeout,它只会获取第一次迭代。

如何更可靠地获取数据以包含所有数据?

io.on('connection', function(socket) {
    authorize (socket, function(shop_id) {
        setInterval(function() {
            var sql = "SELECT * FROM `stats` WHERE `shop_id` = " + connection.escape(shop_id) +
            " AND `created` > DATE_SUB(NOW(), INTERVAL 2 SECOND)";
            var query = connection.query(sql, function(err, rows, fields) {
                if (err == null) {
                    console.log (rows);
                    socket.emit('newData', rows);
                }
            });
        }, 2000);
     });
});

1 个答案:

答案 0 :(得分:2)

MySQL的设计不是每2秒钟就会被拉一次。这不是一个神道系统架构,您将在以后遇到更多问题,绝对是在可扩展性方面。

setInterval不精确,并不保证它会在绝对2000毫秒内睡眠,它可能会在2001年,2200年甚至50小时内睡眠。

要解决此问题,请将NodeJS脚本中提取的最新created存储在变量中,然后获取上次收到created之后创建的所有行。这将获得每一条记录,不会遗漏记录。

io.on('connection', function(socket) {


 authorize (socket, function(shop_id) {
        setInterval(function() {
            var lastCreated = toMySQLDate(new Date());
            var sql = "SELECT * FROM `stats` WHERE `shop_id` = " + connection.escape(shop_id) +
            " AND `created` > " + lastCreated + " ORDER BY `created` DESC";
            var query = connection.query(sql, function(err, rows, fields) {
                if (err == null) {
                    if (rows.length) {
                        lastCreated = toMySQLDate(rows[0].created);
                    }
                    console.log (rows);
                    socket.emit('newData', rows);
                }
            });
        }, 2000);
     });
});

function toMySQLDate(date) {
    return date.toISOString().slice(0, 19).replace('T', ' ');
}