Background note
Recently, there is the following scene in a work project:
Use Node.js express framework to implement a file system server side, which has an API for uploading files on the client side. The client uses Node.js HttpClient to call the server-side API to upload files.
The client has no problems when uploading small files. When uploading large files, the httpClient request reports the following error.
{ [Error: socket hang up] code: 'ECONNRESET' }
I googled a lot of information, and finally looked at the relevant source code of Node.js and finally learned the cause and solution of the problem.
problem causes
The reason for this problem is: The HttpServer provided by Node.js has a default timeout of 2 minutes. When the processing time of a request exceeds 2 minutes, HttpServer will automatically close the socket of the request, so the client receives ECONNRESET Error message again . Node.js can refer to the source code .
Below we use an example to verify.
Service-Terminal:
The server side uses the express framework to register a GET method routing processing function with a path of “”. In the route processing function, the timeout processing is set through the setTimeout method, and the request will be responded to after the timeout is 3 minutes.
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......" );
});
Client:
The client requests the server-side interface by calling the http.request method, and prints the returned information.
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();
Start the server first, then start the client. The result of the request is as follows:
Service-Terminal:
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 Nov21 : 05 : 22 -timeout
Client:
bash- 3.2 $ node app.js
12 Nov 21 : 02 : 22 - start request...
12 Nov 21 : 04 : 22 -{[Error: socket hang up] code: ' ECONNRESET ' }
From the above running results, it can be seen that the client reported an error ECONNRESET after waiting for 2 minutes for the request.
solution
Solution: Call the server.setTimeout() method on the server side to set the server-side timeout to a larger value or directly turn off the timeout mechanism (set the timeout time to 0 to turn it off) .
Just use the above code, the client remains unchanged, and the server calls the server.setTimeout() method at the end of the file, as shown below,
var server = app.listen(3001, function () {
sutil.log( "server listening at port 3001......" );
});
server.setTimeout( 0)
Start the server first, and then start the client, the results are as follows:
Service-Terminal:
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
Client:
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
It can be seen from the above running results that the client can normally receive the return result from the server.
(done)