1

因此,我在 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);

如果有人可以对此提供任何帮助,我将不胜感激。几天来,我一直把头撞在桌子上,试图解决这个问题,并且真的很想解决这个问题,以便我可以继续前进。非常感谢您!

4

2 回答 2

0

你能试着把console.log(socket_id);

  1. 之后form = forms[socket_id];
  2. 之后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)
);
于 2012-08-12T23:22:13.390 回答
0

问题是您没有声明socket_idand formvar因此它们实际上是global.socket_idandglobal.form而不是您的请求处理程序的局部变量。因此,由于回调是指全局而不是正确的闭包,因此单独的请求会相互交叉。

rdrey's solution works because it bypasses that problem (though only for socket_id; if you were to change the code in such a way that one of the callbacks referenced form you'd get in trouble). Normally you only need to use his technique if the variable in question is something that changes in the course of executing the outer function (e.g. if you're creating closures within a loop).

于 2012-08-13T04:20:35.363 回答