你能检测到客户端跟上 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 操作很快,在下一个语句中,循环将休眠直到截止日期,从而允许服务器为其他客户端提供服务。