簡體   English   中英

Express.js 文件上傳:60 秒超時和 HTTP 連接超時錯誤

[英]Express.js File Upload : 60s timeouts and HTTP connection timeout errors

我將很快解釋我的應用程序的作用:

  1. 客戶端上傳文檔
  2. 它被處理
  3. 服務器創建 pdf 的快照圖像
  4. 服務器發送回快照圖像的路徑

現在的問題是,從步驟 (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中間件模塊來代替express.multipart()

此更改解決了 1/2 的問題,因為它消除了我之前遇到的 Express.js 多部分錯誤。

這意味着我的程序在 60 秒后繼續運行,這很好,但在同樣的 60 秒后我仍然從客戶端收到 HTTP 超時。

現在我知道像 Chrome 這樣的瀏覽器可以修復 60 秒超時,但我的問題如下:

  • 有沒有辦法防止這個 HTTP 超時在 60 秒后發生?

  • 如果沒有辦法,其他應用程序如何解決這個問題? 我對多個並發用戶必須爭奪文件系統訪問權限的情況特別感興趣。

先感謝您 !

這里有幾個測試用例,我通過從不使用res.send()回答請求並每 10 秒輪詢tmp目錄中的文件名來模擬長時間處理,只是為了檢查我的文件何時消失(有時是 60 秒超時,有時是 120 秒超時) )。

測試案例 n°1 - 使用舊版express.bodyParser()中間件:

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');

測試案例 n°2 - 使用mulster中間件:

var express = require('express');
var multer = require('multer');
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.json());
app.use(express.urlencoded());
app.use(multer({
    dest: os.tmpDir()
}));

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 file_path = req.files.pdf.path;
    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].split('.')[0].length === 32 || 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');

這個問題看起來與這個問題非常相似。 60 秒超時很可能來自底層套接字,可以通過以下方式修復:

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

據我所知(在這兩種情況下)您都有一個用於 POST 請求的路由處理程序,但在該處理程序中您沒有發送響應。 你也應該在那里使用res.send 否則用戶根本不會得到響應。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM