【发布时间】:2018-07-04 22:44:34
【问题描述】:
如何使用 socket.io 在节点服务器上处理并发文件写入请求。我用这个来写:
fs.writefile('abc.txt','datatobewritten','utf8',function(err){});
我有一个 abc.txt 文件,假设两个用户尝试同时在这个文件上写入,然后我得到一个错误,那么我该如何排队多个请求。
【问题讨论】:
-
尝试写成同步方法
如何使用 socket.io 在节点服务器上处理并发文件写入请求。我用这个来写:
fs.writefile('abc.txt','datatobewritten','utf8',function(err){});
我有一个 abc.txt 文件,假设两个用户尝试同时在这个文件上写入,然后我得到一个错误,那么我该如何排队多个请求。
【问题讨论】:
您必须同步写入。
对于单个 nodejs 实例,您可以使用简单队列,如下所示:
module.exports = function(path, content, cb){
var queue = queues[path];
if (queue == null)
queue = queues[path] = new Queue;
queue.add(path, content, (err) => {
cb(err);
queue.next();
});
};
var fs = require('fs');
var queues = {};
class Queue {
constructor () {
this.queue = [];
}
next () {
if (this.queue.length === 0)
return;
var [path, content, cb] = this.queue[0];
fs.writeFile(path, content, 'utf8', (err) => {
this.queue.shift();
cb(err);
});
}
add (...args) {
this.queue.push(args);
if (this.queue.length === 1) {
this.next();
}
}
}
在多进程实例中,您必须使用一些锁定,例如使用lockfile。
var lockFile = require('lockfile');
var fs = require('fs');
module.exports = function(path, content, cb) {
lockFile.lock('foo.lock', function (err) {
if (err) return cb(err);
fs.writeFile(path, content, cb);
lockFile.unlock('foo.lock');
});
}
为了获得更好的性能,您甚至可以在此处结合使用 2 种方法。
【讨论】:
fs.writeFile 完成后才会调用回调,因此假设有一百万个请求在同一个文件上写入内容,那么队列中的最后一次写入可能需要很长时间才能完成。
你应该写一个模块名称logs或者你喜欢的任何东西。
logs.js
var fs = require('fs');
var writeStream = fs.createWriteStream('./abc.txt');
module.exports = {
/* PUSH */
write: function (message, cb) {
writeStream.write(message, cb);
}
}
然后在你的 socket.io 相关模块中只需要顶部的模块就像
var logs = require('./logs');
并在 socket.io 回调中写入这样的消息! :)
logs.write('datatobewritten');
底线 "使用
fs.createWriteStream而不是fs.writefile"
希望这是有道理的:)
【讨论】: