Express.js文件上传:60s超时和HTTP连接超时错误

时间:2014-03-21 17:58:25

标签: node.js file-upload express connect multipart

我会很快解释我的应用程序的作用:

  1. 客户端上传文档
  2. 处理完毕
  3. 服务器创建pdf
  4. 的快照图像
  5. 服务器发送回快照图像的路径
  6. 现在的问题是,从步骤(1)到(4)的整个过程需要超过60秒。

    起初我有一个使用旧express.bodyParser()的代码,但在60秒后我会收到以下错误:

    Error: Request aborted
        at IncomingMessage.onReqAborted (/DIR_TO_NODE/node/file-upload-error/node_modules/express/node_modules/connect/node_modules/multiparty/index.js:131:17)
        at IncomingMessage.EventEmitter.emit (events.js:92:17)
        at abortIncoming (http.js:1911:11)
        at Socket.serverSocketCloseListener (http.js:1923:5)
        at Socket.EventEmitter.emit (events.js:117:20)
        at TCP.close (net.js:466:12)
    

    并删除操作系统tmp目录中的文件。

    所以我决定使用替换mulster的{​​{1}}中间件模块。

    此更改解决了问题的1/2,因为它删除了我之前得到的Express.js多部分错误。

    这意味着我的程序现在在60s后继续运行,这很好,但是在相同的60s之后我仍然从客户端获得HTTP超时。

    现在我知道像Chrome这样的浏览器可以修复60秒超时,但我的问题如下:

    • 无论如何都要防止60秒后发生HTTP超时?

    • 如果没办法,其他应用程序如何解决这个问题?我对多个并发用户必须争取文件系统访问权限的情况特别感兴趣。

    提前谢谢!

    这里有一些测试案例,我通过永远不会使用express.multipart()回复请求来模拟长时间处理,并且每隔10秒轮询res.send()目录中的文件名,以检查我的文件何时消失(有时60秒超时,有时120秒超时)。

    TEST CASE n°1 - 使用旧版tmp中间件:

    express.bodyParser()

    TEST CASE n°2 - 使用var express = require('express'); var path = require('path'); var app = express(); var fs = require('fs'); var os = require('os'); var pid = process.pid.toString(); var interval; app.use(express.bodyParser()); app.get('/', function (req, res) { res.send([ '<form method="post" enctype="multipart/form-data">' + '<p>Image: <input type="file" name="pdf" /></p>' + '<p><input type="submit" value="Upload" /></p>' + '</form>' ].join('')); }); app.post('/', function (req, res, next) { var file_path; if(req.files.pdf) { file_path = req.files.pdf.path; } else { file_path = os.tmpDir() + 'test'; } var filename = path.basename(file_path); var dir = path.dirname(file_path); console.log('\n> PID: ' + pid); console.log('> Filepath: ' + dir); console.log('> Filename: ' + filename); var count = 0; clearInterval(interval); interval = setInterval(function () { count++; console.log('\n> Interval: ' + (count * 10) + ' seconds'); var files = fs.readdirSync(dir); for(var i = 0; i < files.length; i++) { if(files[i].substr(0, pid.length) === pid) { console.log('\t-> File present: ' + files[i]); } } }, 10000); }); app.listen(3000); console.log('Express started on port 3000'); 中间件:

    mulster

2 个答案:

答案 0 :(得分:1)

问题看起来与this question非常相似。 60 秒超时很可能来自底层套接字,可以通过以下方式修复:

app.post('/', function (req, res, next) { {
    // 10 minute timeout just for POST to /
    req.socket.setTimeout(10 * 60 * 1000);
    
    // ...

});

答案 1 :(得分:0)

据我所知(在两种情况下)你都有一个POST请求的路由处理程序,但是在那个处理程序中你没有发送响应。你也应该在那里使用res.send。否则用户根本不会得到回应。