nodejs的http.request躺坑记录

nodejs的http.request躺坑记录

1、http.request之response.on("data",(chunk:Buffer)=>{})的chunk大小

​ 由于nodejs的response.on("data")每次从服务端读取的chunk大小最大是65535Byte,并且查很多网站都找不大这个说明点所以狠狠踩了这个坑。这个65535有什么影响呢。本来编写的服务端通过post给客户端返回一个10MB大小的文件,数据以Buffer格式写入到响应体内。最后发现在本地127地址下居然需要6秒甚至更多的响应时间才能把文件传输到客户端。我寻思一个本地服务器tmd再怎么慢也不能那么慢,本地随随便便跑50MB/s肯定没问题。通过反反复复debug服务端的发送chunk大小和客户端chunk的大小都没发现问题,最后一看ondata的chunk结果每次最大不超过65535,10MB居然调用了605次ondata才接收完毕。每次耗时10ms左右,真的服了。关键是在这像垃圾桶一样的中文互联网下也找不到这个问题的说明。Stack Overflow也没找到相关情况。

​ 解决办法:不使用on("data"),改成on("readable"),在回调内通过response.read()手动读取

原本的代码:
let data:Buffer = Buffer.from([])
response.on("data",(chunk:Buffer)=>{
    // 拼接data,chunk最高水准为 65535 Byte
	data = Buffer.concat([data, chunk])
})
response.on("end",()=>{
    // 执行请求回调
    console.log(data.length)
})

修改后的代码:
let data:Buffer = Buffer.from([])
response.on("readable",()=>{
	let buff = null;
	// 每次读取5MB大小
    while((buff=response.read(5*1024*1024)) != null){
		data = Buffer.concat([data, buff]);
	}
})
response.on("end",()=>{
    // 执行请求回调
    console.log(data.length)
})

2、response.on("end",()=>{})的触发条件

​ 本来httpserver就有一个response.end()的接口,就让初学者以为调用了这个end,客户端的on("end")就会触发。实际上并不是,on("end")表示的是当缓冲区有服务端响应的内容时,如果通过on("data")或on("readable")取出完毕后就会触发。

​ 一句话说明白:如果response不监听response.on("data")或者response.on("readable"),则response.on("end")不会被触发。你说坑不坑,tnnd

posted @ 2023-12-12 17:33  麦块程序猿  阅读(142)  评论(0编辑  收藏  举报