[英]I am unable to update Flow control window in HTTP2 implementation, so the client is unable to send the rest of the data
I am implementing simple asyncio HTTP2 server and client in Python 3.6. 我在Python 3.6中实现了简单的asyncio HTTP2服务器和客户端。 It requires to implement Flow control.
它需要实现Flow控制。 I have set the flow control window to 2048 bytes on client side with function self.outbound_flow_control_window=2048, after the clients send a 2048 byte chunk of data, server is not processing and acknowledging the received data so the client can send another chunk of 2048 bytes
我在客户端将流控制窗口设置为2048字节,函数为self.outbound_flow_control_window = 2048,客户端发送2048字节的数据块后,服务器没有处理并确认收到的数据,因此客户端可以发送另一块2048字节
i have already tried these functions, self.conn.acknowledge_received_data(2048, event.stream_id) self.conn.increment_flow_control_window(2048, event.stream_id) 我已经尝试过这些函数,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)
After receiving data (2048 bytes) from client, i want the server to acknowledge and update the client that it can send more data now, but flow_control_windows on client remains 0, even after receiving window update frames 从客户端接收数据(2048字节)后,我希望服务器确认并更新客户端,它现在可以发送更多数据,但客户端上的flow_control_windows仍然为0,即使在接收到窗口更新帧之后
Do you have the example server without flow control working? 你有没有流量控制的示例服务器吗? If not do so.
如果不这样做。
https://github.com/python-hyper/hyper-h2/blob/master/examples/asyncio/asyncio-server.py https://github.com/python-hyper/hyper-h2/blob/master/examples/asyncio/asyncio-server.py
You are mixing manual and automatic flow control. 您正在混合手动和自动流量控制。 Reread the automatic flow control section here and use the automatic control.
重新读取此处的自动流量控制部分并使用自动控制。
https://python-hyper.org/projects/h2/en/stable/advanced-usage.html https://python-hyper.org/projects/h2/en/stable/advanced-usage.html
This automatic strategy is built around a single method: acknowledge_received_data.
此自动策略围绕单个方法构建: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.
此方法与increment_flow_control_window之间的主要区别在于,acknowledge_received_data方法不保证它将发出WINDOW_UPDATE帧,如果这样做,则不一定仅为流或仅为帧发出它们。 Instead, the WINDOW_UPDATE frames will be coalesced: they will be emitted only when a certain number of bytes have been freed up.
相反,WINDOW_UPDATE帧将被合并:只有在释放了一定数量的字节时才会发出它们。
Now look at the curio example which uses flow control. 现在看一下使用流量控制的古玩示例。 If you are receiving the window update events from the server likely you are not handling stream id 0 properly.
如果您从服务器接收窗口更新事件,可能是您没有正确处理流ID 0。
https://github.com/python-hyper/hyper-h2/blob/master/examples/curio/curio-server.py https://github.com/python-hyper/hyper-h2/blob/master/examples/curio/curio-server.py
Specifically the send data function: 特别是发送数据功能:
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())
If you want to send 4k bytes you wait on the flow control window, send your 2k bytes then wait again on the flow control window. 如果要发送4k字节,请在流控制窗口中等待,发送2k字节,然后在流控制窗口再次等待。
If you are receiving the window update you should have code like this 如果您收到窗口更新,您应该有这样的代码
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.