gpt4 book ai didi

python-asyncio - 我无法在 HTTP2 实现中更新流量控制窗口,因此客户端无法发送其余数据

转载 作者:行者123 更新时间:2023-12-01 15:54:05 24 4
gpt4 key购买 nike

我正在 Python 3.6 中实现简单的 asyncio HTTP2 服务器和客户端。它需要实现流量控制。我在客户端使用函数 self.outbound_flow_control_window=2048 将流量控制窗口设置为 2048 字节,在客户端发送 2048 字节的数据 block 后,服务器不处理和确认接收到的数据,因此客户端可以发送另一 block 2048字节

我已经尝试过这些功能,self.conn.acknowledge_received_data(2048, event.stream_id)self.conn.increment_flow_control_window(2048, event.stream_id)

elif isinstance(event, DataReceived):
self.receive_data(event.data, event.stream_id)
self.conn.acknowledge_received_data(2048, event.stream_id)
self.conn.increment_flow_control_window(2048, event.stream_id)

从客户端接收到数据(2048 字节)后,我希望服务器确认并更新客户端它现在可以发送更多数据,但客户端上的 flow_control_windows 仍然为 0,即使在接收到窗口更新帧之后也是如此

最佳答案

你有没有流量控制的示例服务器吗?如果不这样做。

https://github.com/python-hyper/hyper-h2/blob/master/examples/asyncio/asyncio-server.py

您正在混合使用手动和自动流量控制。重读此处的自动流量控制部分并使用自动控制。

https://python-hyper.org/projects/h2/en/stable/advanced-usage.html

This automatic strategy is built around a single method: acknowledge_received_data. This method flags to the connection object that your application has dealt with a certain number of flow controlled bytes, and that the window should be incremented in some way. Whenever your application has “processed” some received bytes, this method should be called to signal that they have been processed.

The key difference between this method and increment_flow_control_window is that the method acknowledge_received_data does not guarantee that it will emit a WINDOW_UPDATE frame, and if it does it will not necessarily emit them for only the stream or only the frame. Instead, the WINDOW_UPDATE frames will be coalesced: they will be emitted only when a certain number of bytes have been freed up.

现在看一下使用流控制的 curio 示例。如果您从服务器接收到窗口更新事件,您可能没有正确处理流 ID 0。

https://github.com/python-hyper/hyper-h2/blob/master/examples/curio/curio-server.py

特别是发送数据函数:

 while True:
while not self.conn.local_flow_control_window(stream_id):
await self.wait_for_flow_control(stream_id)

chunk_size = min(
self.conn.local_flow_control_window(stream_id),
READ_CHUNK_SIZE,
)

data = fileobj.read(chunk_size)
keep_reading = (len(data) == chunk_size)

self.conn.send_data(stream_id, data, not keep_reading)
await self.sock.sendall(self.conn.data_to_send())

如果你想发送 4k 字节你在流量控制窗口等待,发送你的 2k 字节然后在流量控制窗口再次等待。

如果你正在接收窗口更新,你应该有这样的代码

async def window_updated(self, event):
"""
Unblock streams waiting on flow control, if needed.
"""
stream_id = event.stream_id

if stream_id and stream_id in self.flow_control_events:
evt = self.flow_control_events.pop(stream_id)
await evt.set()
elif not stream_id:
# Need to keep a real list here to use only the events present at
# this time.
blocked_streams = list(self.flow_control_events.keys())
for stream_id in blocked_streams:
event = self.flow_control_events.pop(stream_id)
await event.set()
return

关于python-asyncio - 我无法在 HTTP2 实现中更新流量控制窗口,因此客户端无法发送其余数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54616728/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com