你能检测到客户端跟上 websocket 消息流的程度吗?
Can you detect how well a client is keeping up with a stream of websocket messages?
我正在编写一个视频流服务,并且正在考虑通过 websockets 流式传输视频。
我预见到的一个问题是客户端没有足够的带宽来接收流,所以我希望能够检测到我是否领先于我的客户端太远,并将消息降低到较低的帧率或质量。
你能检测到龙卷风何时发送太多客户端无法接收吗?
您不必担心网速慢;但是您确实需要担心快速网络。
您无法向网络写入超过客户端能够接受的数据。所以你不会出人头地。
假设您正在分块阅读和发送视频。您的代码可能如下所示:
while True:
self.write(chunk)
await self.flush() # write chunk to network
await self.flush()
语句将暂停循环,直到将块写入网络。所以如果它是一个慢速网络,它会暂停更长时间。如您所见,您不必担心会远远领先于客户。
但是,如果您的客户端网络速度很快,那么 flush
操作也会非常快,这可能会阻塞您的服务器,因为此循环将保持 运行 直到所有数据发送完毕并且 IOLoop 将没有机会为其他客户端提供服务。
对于这些情况,tornado 的维护者 Ben Darnell 在 google forums thread 中提供了一个非常聪明的解决方案,他称之为:
serve each client at a "fair" rate instead of allowing a single client to consume as much bandwidth as you can give it.
这是代码(直接取自 Ben Darnell 的 post):
while True:
# Start the clock to ensure a steady maximum rate
deadline = IOLoop.current().time() + 0.1
# Read a 1MB chunk
self.write(chunk)
await self.flush()
# This sleep will be instant if the deadline has already passed;
# otherwise we'll sleep long enough to keep the transfer
# rate around 10MB/sec (adjust the numbers above as needed
# for your desired transfer rate)
await gen.sleep(deadline)
现在,即使 flush
操作很快,在下一个语句中,循环将休眠直到截止日期,从而允许服务器为其他客户端提供服务。
我正在编写一个视频流服务,并且正在考虑通过 websockets 流式传输视频。
我预见到的一个问题是客户端没有足够的带宽来接收流,所以我希望能够检测到我是否领先于我的客户端太远,并将消息降低到较低的帧率或质量。
你能检测到龙卷风何时发送太多客户端无法接收吗?
您不必担心网速慢;但是您确实需要担心快速网络。
您无法向网络写入超过客户端能够接受的数据。所以你不会出人头地。
假设您正在分块阅读和发送视频。您的代码可能如下所示:
while True:
self.write(chunk)
await self.flush() # write chunk to network
await self.flush()
语句将暂停循环,直到将块写入网络。所以如果它是一个慢速网络,它会暂停更长时间。如您所见,您不必担心会远远领先于客户。
但是,如果您的客户端网络速度很快,那么 flush
操作也会非常快,这可能会阻塞您的服务器,因为此循环将保持 运行 直到所有数据发送完毕并且 IOLoop 将没有机会为其他客户端提供服务。
对于这些情况,tornado 的维护者 Ben Darnell 在 google forums thread 中提供了一个非常聪明的解决方案,他称之为:
serve each client at a "fair" rate instead of allowing a single client to consume as much bandwidth as you can give it.
这是代码(直接取自 Ben Darnell 的 post):
while True:
# Start the clock to ensure a steady maximum rate
deadline = IOLoop.current().time() + 0.1
# Read a 1MB chunk
self.write(chunk)
await self.flush()
# This sleep will be instant if the deadline has already passed;
# otherwise we'll sleep long enough to keep the transfer
# rate around 10MB/sec (adjust the numbers above as needed
# for your desired transfer rate)
await gen.sleep(deadline)
现在,即使 flush
操作很快,在下一个语句中,循环将休眠直到截止日期,从而允许服务器为其他客户端提供服务。