最近在工做項目中有下面一個場景:node
使用Node.js的express框架實現了一個文件系統服務器端,其中有個API用於客戶端上傳文件。客戶端使用Node.js的HttpClient來調用服務器端的API上傳文件。git
客戶端在上傳小文件時沒有任何問題,在上傳大文件時httpClient請求報錯了下面的錯誤,github
{ [Error: socket hang up] code: 'ECONNRESET' }
google了不少資料,最後看了一下Node.js的相關源碼終於知道了該問題的緣由和解決辦法。express
出現該問題的緣由是:Node.js提供的HttpServer默認設置了超時時間爲2分鐘,當一個請求的處理時間超過2分鐘,HttpServer會自動將該請求的socket關閉掉,因而客戶端便收到了 ECONNRESET 的錯誤信息了。能夠參考Node.js的源碼。bash
下面咱們使用了一個例子來驗證一下。服務器
服務器端:app
服務器端使用express框架,註冊了一個路徑爲「「 的 GET 方法路由處理函數。在該路由處理函數中,經過setTimeout方式設置了超時處理,3分鐘後超時纔會對請求進行相應。框架
const express = require('express'); const util = require('util'); const app = express(); app.get("/", function(req, res, next) { util.log("Received a request."); setTimeout(function() { res.setHeader('transfer-encoding', 'chunked'); res.status(200); util.log("timeout") res.write("hello world"); res.end(); }, 3 * 60 * 1000) }); var server = app.listen(3001, function() { sutil.log("server listening at port 3001......"); });
客戶端:socket
客戶端經過調用http.request方法請求服務器端的接口,並打印返回的信息。函數
const http = require('http'); const util = require('util') var opt = { host: 'localhost', port: 3001, method: 'GET', }; var req = http.request(opt, function(res) { util.log('STATUS:', res.statusCode); res.setEncoding('utf8'); var resultText = ''; res.on('data', (chunk) => { resultText += chunk; }); res.on('end', () => { util.log(resultText); }); }); req.on('error', (e) => { util.log(e); }); util.log("start request...") req.end();
先啓動服務器端,而後啓動客戶端。請求的結果以下所示:
服務器端:
bbash-3.2$ node app.js 12 Nov 21:02:16 - server listening at port 3001...... 12 Nov 21:02:22 - Received a request. 12 Nov 21:05:22 - timeout
客戶端:
bash-3.2$ node app.js 12 Nov 21:02:22 - start request... 12 Nov 21:04:22 - { [Error: socket hang up] code: 'ECONNRESET' }
經過上面的運行結果能夠看到,客戶端在請求等待了2分鐘以後,就報錯了 ECONNRESET 的錯誤。
解決措施:調用服務器端的server.setTimeout()方法將服務器端的超時設置得大一點或者直接將超時機制關閉(將超時時間設置爲0便可關閉)。
就使用上面的代碼,客戶端不變,服務器在文件最後調用server.setTimeout()方法,以下所示,
var server = app.listen(3001, function() { sutil.log("server listening at port 3001......"); }); server.setTimeout(0)
先啓動服務器端,而後再啓動客戶端,運行結果以下:
服務器端:
bash-3.2$ node app.js 12 Nov 21:37:22 - server listening at port 3001...... 12 Nov 21:37:29 - Received a request. 12 Nov 21:40:29 - timeout
客戶端:
bash-3.2$ node app.js 12 Nov 21:37:29 - start request... 12 Nov 21:40:29 - STATUS: 200 12 Nov 21:40:29 - hello world
從上面運行結果可見,客戶端可以正常接收到服務器端的返回結果了。
(done)