Express.js время ожидания соединения против времени ожидания сервера - PullRequest
1 голос
/ 26 марта 2019

Я использую экспресс и Подключите промежуточное программное обеспечение для тайм-аута для обработки тайм-аутов.

Это прекрасно работает, но для сервера по умолчанию 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')); 

Как я могу избежать этого?Я что-то упустил?

1 Ответ

1 голос
/ 26 марта 2019

Если вы хотите использовать промежуточное программное обеспечение 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');

});
...