最近在工做项目中有下面一个场景: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)