繁体   English   中英

使用socket.io排队

[英]Queuing using socket.io

我正在使用node.js每10秒查询一次MySQL数据库表。 使用socket.io,每隔10秒查询一次数据库后,每个连接的浏览器将从该查询中接收到唯一的一行行。

问题:使用我实施此方法的方式,每隔10秒就有一个以上的浏览器接收相同的行集。 我使用了一些检出系统(如下所示)来标记已经发送到另一个浏览器的行,但是它似乎并不能一直工作。 如何保证每个浏览器每次都获得唯一的行集?

换句话说,其他浏览器同时查询数据库比锁定行要快!

实作

每隔10秒就会发生以下情况

  1. Node.js应用程序查询MySQL数据库表SELECT * FROM table WHERE checkout = 0
  2. 如果返回结果,则node.js服务器io.sockets.send向所有连接的浏览器io.sockets.send一条消息,指出行可用
  3. 所有连接的客户端socket.emit('ready')响应
  4. 服务器接收到ready发射,再次查询数据库以选择3行,然后更新表以将这3行的checkout列设置为1
  5. 然后,服务器将数据库查询结果发送给客户端

显然,与第一个浏览器使用checkout = 1更新行相比,第二个浏览器引发SELECT...查询的时间似乎更少。 还有另一种方法可以进行此排队吗?

屏幕截图

正如您在同时打开两个浏览器的屏幕快照中看到的那样,通常两个浏览器都将获得相同的行集。 如图所示,这些行的id是console.log 在此处输入图片说明

Node.js

io.sockets.on('connection', function(socket) {
    // Client ready to take jobs after receiving broadcast
    socket.on('ready', function() {
        getListings(function(listings) {
            socket.emit('job', listings);   // send jobs
        });
    });

});

var getListings = function(callback) {
    client.query('SELECT * FROM table ' + 
                'WHERE job_checkout = 0 ' +
                'ORDER BY listing_id ASC ' +
                'LIMIT 0, 3', 
                function(error ,results, fields) {
                    if (error) 
                        throw error;
                    // Checkout listing now!
                    checkoutListings(results);
                    callback(results);
                });
};

var checkoutListings = function(listings) {
    for (var i = 0; i < listings.length; i++) {
        checkoutListing(listings[i]);
    }
}

var checkoutListing = function(listing) {
    client.query('UPDATE table ' + 
                    'SET job_checkout = 1 ' +
                    'WHERE listing_id = ?',
                    [ listing.listing_id ]);
}

一种简单的解决方案(如果性能不是大问题)是一种事务,它锁定您触摸要读取的每一行-如果其他任何人试图在您的选择和插入之间进行读取,那么他们将不得不等到您的锁定被释放为止

在选择行之前更新它们。 例如

update table 
set job_checkout = uniqueNumber 
where job_checkout = 0
limit 10

uniqueNumber可以是进程/线程ID,也可以是浏览器客户端ID,也可以是在node.js环境中适合的东西(我不熟悉)。 现在,选择具有唯一job_checkout的行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM