似乎无法从node-formidable获取进度事件通过socket.io发送到正确的客户端

时间:2012-08-12 23:08:23

标签: ajax node.js socket.io multipartform-data formidable

所以我在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);

如果有人能对此提供任何帮助,我将不胜感激。我一直在我的桌子上撞了几天试图弄清楚这个,并且真的只是想解决这个问题以便我继续前进。非常感谢你!

2 个答案:

答案 0 :(得分:0)

您可以尝试放置console.log(socket_id);

  1. form = forms[socket_id];
  2. 之后
  3. progress = (bytesReceived / bytesExpected * 100).toFixed(0);之后,拜托?
  4. 我觉得你可能必须将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声明formvar,因此它们实际上是global.socket_idglobal.form而不是局部变量您的请求处理程序。因此,单独的请求会相互跳过,因为回调是指整数而不是正确的闭包。

rdrey的解决方案有效,因为它绕过了这个问题(虽然只针对socket_id;如果您要改变代码的方式,其中一个回调引用form就会遇到麻烦) 。通常,如果有问题的变量在执行外部函数的过程中发生变化(例如,如果您在循环中创建闭包),则只需要使用他的技术。