Ответ 1
К сожалению, я никогда не нашел подходящего способа сделать это. Я прибегал к довольно ужасной утиной, но это работает для моего конкретного случая использования. Если кто-то еще споткнется вместе с этой проблемой, вы можете начать с этого и уточнить оттуда.
Модуль №1: "Дополнительные события"
Все, что делает этот модуль, это заставить объект ответа испускать событие finishBeforeSocketDestroy
. Поскольку мне понадобилось это событие в нескольких местах в моем приложении, я фактически сделал отдельный модуль только для этого утиного пунша. app.use()
до модуля № 2.
module.exports = function (req, res, next) {
var end = res.end;
res.end = function () {
res.end = end;
res.emit('finishBeforeSocketDestroy');
res.end.apply(this, arguments);
}
next();
}
Модуль №2: "Статистика"
Этот модуль создает объект req.stats
, содержащий всевозможные полезные свойства для отслеживания использования полосы пропускания во время использования соединения и после его завершения.
var pollTime = 1000;
module.exports = function (req, res, next) {
var pollInterval;
function pollStats () {
if (typeof req.stats._lastMeasuredTime === 'object') {
var secondsSinceLastMeasurement = ((new Date() - req.stats._lastMeasuredTime) / 1000);
req.stats.averageRate = {
read: (req.socket.bytesRead - req.stats.bytesRead) / secondsSinceLastMeasurement,
write: (req.socket.bytesWritten - req.stats.bytesWritten) / secondsSinceLastMeasurement
};
}
req.stats._lastMeasuredTime = new Date();
req.stats.bytesRead = req.socket.bytesRead;
req.stats.bytesWritten = req.socket.bytesWritten;
}
req.stats = {
startTime: new Date(),
endTime: null,
averageRate: {read: null, write: null},
bytesRead: req.socket.bytesRead,
bytesWritten: req.socket.bytesWritten,
_lastMeasuredTime: new Date()
};
pollInterval = setInterval(pollStats, pollTime);
res.on('finishBeforeSocketDestroy', function () {
clearInterval(pollInterval);
pollStats();
req.stats.endTime = new Date();
});
next();
}
Как я сказал... беспорядочно. Я только отправляю его, так как утиная перфорация может быть вашим единственным вариантом. Также будьте осторожны, что socket
может повторно использоваться для нескольких HTTP-запросов, что может привести к двойному подсчету нескольких байтов, если вы не будете осторожны.