如何在Node中限制HTTP请求的带宽?

qybjjes1  于 2023-01-16  发布在  Node.js
关注(0)|答案(3)|浏览(199)

我正在尝试限制HTTP请求使用的带宽(下载/上传速度)。我正在使用NPM包stream-throttle。我创建了一个自定义HTTP代理来通过Throttle示例传输套接字,并对5 MB文件的下载速度进行计时。

const http = require("http");
const net = require("net");
const {Throttle, ThrottleGroup} = require("stream-throttle");

const maxBandwidth = 100;
// an example 5MB file of random data
const str = "http://212.183.159.230/5MB.zip";

// this pipes an instance of Throttle
class SlowAgent extends http.Agent {
    createConnection(options, callback){
        const socket = new net.Socket(options);
        socket.pipe(new Throttle({rate: maxBandwidth}));
        socket.connect(options);
        return socket;
    }
}

const options = {
    // this should slow down the request
    agent: new SlowAgent()
};

const time = Date.now();
const req = http.request(str, options, (res) => {
    res.on("data", () => {
    });
    res.on('end', () => {
        console.log("Done! Elapsed time: " + (Date.now() - time) + "ms");
    });
});

req.on('error', (e) => {
    console.error(`problem with request: ${e.message}`);
});

req.on("end", () => {
    console.log("done");
});

console.log("Request started");
req.end();

不管maxBandwidth的值是什么,或者根本没有使用SlowAgent(我已经尝试注解掉agent: new SlowAgent()),我注意到在运行时间上没有任何差异(大约4000毫秒)。我如何修复我的SlowAgent类?我不理解socket.pipe吗?或者我需要做其他事情吗?
freakish指出要将SlowAgent更改为:

// this pipes an instance of Throttle
class SlowAgent extends http.Agent {
    createConnection(options, callback){
        const socket = new net.Socket(options);
        socket.connect(options);
        return socket.pipe(new Throttle({rate: 10}));
    }
}

但这就带来了一个问题

problem with request: Parse Error: Expected HTTP/ Error: Parse Error: Expected HTTP/
    at Throttle.socketOnData (_http_client.js:456:22)
    at Throttle.emit (events.js:209:13)
    at addChunk (_stream_readable.js:305:12)
    at readableAddChunk (_stream_readable.js:286:11)
    at Throttle.Readable.push (_stream_readable.js:220:10)
    at Throttle.Transform.push (_stream_transform.js:150:32)
    at /home/max/Documents/Personal/node-projects/proxy/node_modules/stream-throttle/src/throttle.js:37:14
    at processTicksAndRejections (internal/process/task_queues.js:75:11) {
  bytesParsed: 0,
  code: 'HPE_INVALID_CONSTANT',
  reason: 'Expected HTTP/',
  rawPacket: <Buffer 47>
}
fumotvh3

fumotvh31#

我设法让它工作,通过做了一个定制的agent和使用createConnection内的http.request选项:

const options = {
    createConnection(options) {
        const socket = new net.Socket();
        return socket.connect({host: options.host, port: options.port});
    },
    hostname: "212.183.159.230",
    path: "/5MB.zip"
};

const time = Date.now();

const req = http.request(options, (res) => {

    res.pipe(new Throttle({rate: 200 * 1024}))
        .on("data", (chunk) => {
            console.log(chunk.length);
        })

    res.on("end", () => {
        console.log("Done! Elapsed time: " + (Date.now() - time) + "ms");
    });
});
6fe3ivhb

6fe3ivhb2#

流媒体带宽控制必须在服务器端和客户端实现。
从**客户的Angular **,

    • 上载速率**可通过限制进行管理

客户端应用或客户端网络层或服务器网络层

    • 下载速率**可通过限制进行管理

服务器应用程序或服务器网络层客户端网络层
请看看这个测试代码.你可以改变双方的速度变量.
环境
Windows 10中的节点v10.16.3。
server.js

var fs = require('fs');  // file system
var http = require('http');
const {ThrottleGroup} = require("stream-throttle");

/**
 * Change to various rate to test
 */
var tg = new ThrottleGroup({rate: 1024*1024}); //1 MiB per sec

/**
 * please copy your own file
 * my file is 4.73 MB (4,961,271 bytes) ,it takes 4~5 sec to send data chunk
 */
var source = "source.jpg"; //

var server = http.createServer((req, res) => {

    var rstream = fs.createReadStream(source);
    rstream
        .pipe(tg.throttle()) //throttle here
        .pipe(res);

    //define event 
    rstream
        .on('open', ()=>{
            console.log('open', new Date())
        })        
        .on('data', (chunk)=>{
            console.log(new Date(), chunk.length) // 65536 bytes
        })
        .on('close', () => {
            console.log('close', new Date())
        });       
});
server.listen(80, '127.0.0.1');  // start
//OUTPUT when client request, max chunk 65536 bytes
>node server.js

open 2019-09-13T05:27:40.724Z
2019-09-13T05:27:40.730Z 65536
2019-09-13T05:27:40.732Z 65536
...
2019-09-13T05:27:44.355Z 65536
2019-09-13T05:27:44.419Z 46071
close 2019-09-13T05:27:44.421Z

client.js
一个二个一个一个
对于真实世界示例,更改client.js限制率和下一行

http.get('http://127.0.0.1/', (res) => {

变成了

http.get('http://i.ytimg.com/vi/ZYifkcmIb-4/maxresdefault.jpg', (res) => {

在现实世界中,随着参与者的增多,网络会变得更加复杂。
服务器端OSI模型〈==〉网络〈==〉客户端OSI模型
因为互联网提供商或运营商会节流他们的端口,这将影响您的上传和下载速率。

k97glaaz

k97glaaz3#

可能是:

const socket = new net.Socket(options);
const throttledSocket = new Throttle({rate: maxBandwidth});
throttledSocket.pipe(socket);
socket.connect(options);
return throttledSocket;

相关问题