Ajax can';似乎无法通过socket.io将进度事件从节点发送到正确的客户端
因此,我正在node.js上通过ajax构建一个多部分表单上传程序,并通过socket.io将进度事件发送回客户端,以显示其上传的状态。一切正常,直到我有多个客户端试图同时上传。最初会发生的情况是,当一个上载正在进行时,当第二个上载启动时,它开始从正在解析的两个表单接收进度事件。原始表单不会受到影响,它只接收自身的进度更新。我尝试创建一个新的强大表单对象,并将其与套接字的会话id一起存储在一个数组中,试图解决这个问题,但现在第一个表单停止接收事件,而第二个表单得到处理。这是我的服务器代码:Ajax can';似乎无法通过socket.io将进度事件从节点发送到正确的客户端,ajax,node.js,socket.io,multipartform-data,formidable,Ajax,Node.js,Socket.io,Multipartform Data,Formidable,因此,我正在node.js上通过ajax构建一个多部分表单上传程序,并通过socket.io将进度事件发送回客户端,以显示其上传的状态。一切正常,直到我有多个客户端试图同时上传。最初会发生的情况是,当一个上载正在进行时,当第二个上载启动时,它开始从正在解析的两个表单接收进度事件。原始表单不会受到影响,它只接收自身的进度更新。我尝试创建一个新的强大表单对象,并将其与套接字的会话id一起存储在一个数组中,试图解决这个问题,但现在第一个表单停止接收事件,而第二个表单得到处理。这是我的服务器代码: va
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);
如果有人能在这方面提供帮助,我将不胜感激。几天来,我一直在用我的头撞我的桌子,试图弄明白这一点,我真的很想解决这个问题,这样我就可以继续前进了。提前非常感谢 您可以尝试放置
console.log(socket\u id)代码>
在form=forms[socket_id]之后代码>和
在progress=(bytesReceived/bytesExpected*100)之后。toFixed(0)代码>,请问
我有种感觉,你可能需要将套接字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)
);
问题是,您没有使用var
声明socket\u id
和form
,因此它们实际上是global.socket\u id
和global.form
而不是请求处理程序的局部变量。因此,单独的请求相互重叠,因为回调是指全局的,而不是正确的闭包
rdrey的解决方案之所以有效,是因为它绕过了这个问题(尽管只适用于socket\u id
;如果您更改代码的方式使其中一个回调引用了表单,您就会遇到麻烦)。通常,只有当所讨论的变量在执行外部函数的过程中发生变化时(例如,如果在循环中创建闭包),您才需要使用他的技术。尝试过这个,它会起作用!完全没有Javascript方面的经验,我不知道您需要这样做才能将外部变量引入事件回调。非常感谢你!没问题。我还是一个新手,并且总是对我的变量在回调中未定义感到惊讶看看这个,你可以用JS做的很棒。谢谢你的额外解释,这也帮助了我的理解!