为Node.js HTTP请求发送/接收的字节数

时间:2013-01-03 05:35:23

标签: node.js

一旦提供了HTTP请求,我想记录发送/接收的字节数。

此数据的简单来源是req.connection.bytesRead / .bytesWritten。但是,这对于HTTP 1.1保持活动连接是有问题的,因为相同的套接字可以用于多个请求。 我需要按请求记录,而不是按连接记录。

解决方案必须放在HTTP方面,但我认为没有记录任何方法来获取我需要的数据。

为Node.js http.Server提供的HTTP请求计算读/写字节的正确方法是什么?

2 个答案:

答案 0 :(得分:15)

不幸的是,我从来没有找到合适的方法来做到这一点。我已经采取了一些相当可怕的鸭子冲孔,但它适用于我的特定用例。如果其他人偶然发现这个问题,你可以从这开始并从那里进行改进。

模块#1:“额外事件”

所有这个模块都是让响应对象发出finishBeforeSocketDestroy事件。由于我在我的应用程序中的一些地方需要这个事件,我有效地为这个鸭子打了一个单独的模块。在模块#2之前app.use()

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请求,如果你不小心,可能会导致你重复计算一些字节。

答案 1 :(得分:0)

只需在每次回复后存储流量值,并计算完成后的差异'或者'结束'处理程序:

// server.onRequest:
  ...
  req._prevBytesWritten = 0;

// response.onFinish/onEnd:
  ...
  responseLen = req.socket.bytesWritten - req._prevBytesWritten;
  req._prevBytesWritten = req.socket.bytesWritten;