【发布时间】:2020-05-09 06:08:59
【问题描述】:
众所周知,libuv 是一个异步网络库。
现在我用libuv编写了一个http下载客户端,但是我不知道如何限制下载时的速度。也就是说,在libuv或异步网络库下读取数据时如何控制IO带宽?
类似问题:
1.How to control the transmission speed under libuv?
2.Rate-limiting plan in libuv #738
【问题讨论】:
众所周知,libuv 是一个异步网络库。
现在我用libuv编写了一个http下载客户端,但是我不知道如何限制下载时的速度。也就是说,在libuv或异步网络库下读取数据时如何控制IO带宽?
类似问题:
1.How to control the transmission speed under libuv?
2.Rate-limiting plan in libuv #738
【问题讨论】:
我最近实现了一个限制代理,我是这样做的:
在本示例中,我假设最大带宽为 100kbps,超时时间为 10ms,并由您自行处理错误。
read_start
read_stop
read_start
我在 Lua 中使用 luvit 进行了此操作,luvit 是 libuv 的包装器(+ 更多),但您应该能够轻松翻译有趣的部分。
这是 Lua 代码的相关部分供参考。请注意,我在这里的写回调中启动了我的计时器,但这应该没什么区别。 send_data_to_upstream 是传入的流读取回调。
local send_next_chunk
local send_data_to_upstream
send_data_to_upstream = function(err, data)
if err then debug_print("Client error:" .. err) end
if data then
-- throttle reads
self.sock.tcp_client:read_stop()
-- chunkify the data
self.chunks = splitByChunk(data, self:_get_chunk_size())
debug_print("[DOWN]", "Client request: " .. #data)
send_next_chunk()
else
-- Client disconnected, cleanup handles
self:disconnect()
debug_print("Client disconnected")
end
end
send_next_chunk = function()
if #self.chunks > 0 then
debug_print("[DOWN]", "Chunks remaining: ", #self.chunks,
"next in:", self.throttle.delay)
timer.setTimeout(self.throttle.delay, function()
-- throttle transfer for consecutive chunks
self.throttle.delay = self.throttle.timeout_ms
-- send next chunk
local head = table.remove(self.chunks, 1)
self.sock.tcp_upstream:write(head, send_next_chunk)
collectgarbage("step")
end)
else
-- restart the client data pump
self.throttle.delay = 0
debug_print("[DOWN]", "Client request completed")
self.sock.tcp_client:read_start(send_data_to_upstream)
end
end
【讨论】: