Я использую экспресс и Connect Timeout Middleware для обработки тайм-аутов.
Он отлично работает, но по умолчанию тайм-аут сервера node http установлен на две минуты.
Поэтому, если я хочу установить промежуточное программное обеспечение тайм-аута на значение, превышающее две минуты, я также должен увеличить тайм-аут http-сервера, чтобы он был немного больше (иначе мой обработчик тайм-аута подключения не вызывается)
const app = express();
const http = new Http.Server(app);
http.setTimeout((4 * 60 * 1000) + 1); <-- Must set this
app.use(timeout('4m'));
Как я могу этого избежать? Я что-то пропустил ?





Если вы хотите использовать промежуточное программное обеспечение connect-timeout, вы не можете избежать его, поскольку промежуточное программное обеспечение не меняет тайм-аут сокета, который по умолчанию равен 2 минутам.
Есть два возможных способа избежать этого: либо с помощью server.setTimeout(), либо с помощью request.setTimeout.
Если вы хотите изменить тайм-аут только для нескольких маршрутов и оставить тайм-аут по умолчанию для остальных, рекомендуемый подход заключается в использовании: request.setTimeout
app.use('/some-routes', (req, res, next) => {
req.setTimeout((4 * 60 * 1000) + 1);
next();
}, timeout('4m'));
Альтернативой установке req.setTimeout значения, превышающего значение connect-timeout, является удаление промежуточного программного обеспечения connect-timeout и использование другого обходного пути, что также не идеально.
Вы можете проверить эту старую проблему Node.js https://github.com/nodejs/node-v0.x-archive/issues/3460
function haltOnTimedout (req, res, next) {
if (!req.timedout) next()
}
app.use('/some-routes', (req, res, next) => {
req.setTimeout(4 * 60 * 1000); // No need to offset
req.socket.removeAllListeners('timeout'); // This is the work around
req.socket.once('timeout', () => {
req.timedout = true;
res.status(504).send('Timeout');
});
next();
});
app.use(haltOnTimedout);
// But if the timeout occurs in the middle of a route
// You will need to check if the headers were sent or if the request timedout
app.get('/some-routes', async(req, res, next) => {
// some async processing...
await asyncOperation();
if (!res.headersSent) // or !req.timedout
res.send('done');
});
Нет, просто так это работает. Если узел закрывает сокет до того, как промежуточное ПО истечет время ожидания запроса, обработчик не будет вызываться, потому что запрос закрыт в этот момент времени. github.com/expressjs/timeout/issues/32