所以我在node.js上的ajax上构建一个多部分表单上传器,并通过socket.io将进度事件发送回客户端,以显示他们上传的状态。一切正常,直到我有多个客户端同时尝试上传。最初会发生一次上传,当第二次上传时,它开始从正在解析的两种表单中接收进度事件。原始表单不会受到影响,它只接收自身的进度更新。我尝试创建一个新的强大的表单对象,并将其与套接字的会话ID一起存储在一个数组中,以尝试解决此问题,但现在第一个表单停止接收事件,而第二个表单被处理。这是我的服务器代码:
var http = require('http'),
formidable = require('formidable'),
fs = require('fs'),
io = require('socket.io'),
mime = require('mime'),
forms = {};
var server = http.createServer(function (req, res) {
if (req.url.split("?")[0] == "/upload") {
console.log("hit upload");
if (req.method.toLowerCase() === 'post') {
socket_id = req.url.split("sid=")[1];
forms[socket_id] = new formidable.IncomingForm();
form = forms[socket_id];
form.addListener('progress', function (bytesReceived, bytesExpected) {
progress = (bytesReceived / bytesExpected * 100).toFixed(0);
socket.sockets.socket(socket_id).send(progress);
});
form.parse(req, function (err, fields, files) {
file_name = escape(files.upload.name);
fs.writeFile(file_name, files.upload, 'utf8', function (err) {
if (err) throw err;
console.log(file_name);
})
});
}
}
});
var socket = io.listen(server);
server.listen(8000);
如果有人能对此提供任何帮助,我将不胜感激。我一直在我的桌子上撞了几天试图弄清楚这个,并且真的只是想解决这个问题以便我继续前进。非常感谢你!
答案 0 :(得分:0)
您可以尝试放置console.log(socket_id);
form = forms[socket_id];
和progress = (bytesReceived / bytesExpected * 100).toFixed(0);
之后,拜托?我觉得你可能必须将socket_id包装在一个闭包中,如下所示:
form.addListener(
'progress',
(function(socket_id) {
return function (bytesReceived, bytesExpected) {
progress = (bytesReceived / bytesExpected * 100).toFixed(0);
socket.sockets.socket(socket_id).send(progress);
};
})(socket_id)
);
答案 1 :(得分:0)
问题是您没有使用socket_id
声明form
和var
,因此它们实际上是global.socket_id
和global.form
而不是局部变量您的请求处理程序。因此,单独的请求会相互跳过,因为回调是指整数而不是正确的闭包。
socket_id
;如果您要改变代码的方式,其中一个回调引用form
就会遇到麻烦) 。通常,如果有问题的变量在执行外部函数的过程中发生变化(例如,如果您在循环中创建闭包),则只需要使用他的技术。