Browser 我可以在WebSocket上进行流量控制吗?

Browser 我可以在WebSocket上进行流量控制吗?,browser,tcp,websocket,Browser,Tcp,Websocket,我正在使用websockets将视频-y图像从服务器(用Go编写)传输到作为HTML页面的客户端。我在下面分享的经验是使用Chrome 我通过websocket的onmessage处理程序接收图像。在接收图像时,我可能需要异步完成许多任务,然后才能显示图像。即使这些任务没有完成,也可能会触发另一个onmessage()。我不想对图像进行排队,因为此时我无法像服务器那样快速地处理图像,而且显示旧图像也没有意义。我也不想丢弃这些图像,我根本不想接收它们 如果客户端使用传统的TCP连接,它将停止从该连

我正在使用websockets将视频-y图像从服务器(用Go编写)传输到作为HTML页面的客户端。我在下面分享的经验是使用Chrome

我通过websocket的onmessage处理程序接收图像。在接收图像时,我可能需要异步完成许多任务,然后才能显示图像。即使这些任务没有完成,也可能会触发另一个onmessage()。我不想对图像进行排队,因为此时我无法像服务器那样快速地处理图像,而且显示旧图像也没有意义。我也不想丢弃这些图像,我根本不想接收它们

如果客户端使用传统的TCP连接,它将停止从该连接读取数据。这将导致填充接收缓冲区,关闭接收窗口,并最终暂停在服务器上发送图像。当客户端开始读取时,接收缓冲区将清空,接收窗口将打开,服务器恢复传输。每次我的服务器开始发送图像时,它都会选择最新的图像。这种选择最新鲜的行为,加上TCP的流控制,在许多情况下确保了合理的行为


websockets所基于的TCP的流量控制功能是否可以与websockets一起使用?我特别感兴趣的是一种依赖于TCP流控制而没有应用程序级流控制的解决方案,因为这往往会导致不必要的额外延迟。

我怀疑您的要求是否可能。中没有该功能的接口。然而,规范所概述的是一项要求,即底层套接字连接必须在使用WebSocket的脚本之外的后台进行管理,以便脚本不会被WebSocket操作阻止。当套接字接收入站数据时,它将数据包装在消息中,并将其排队等待WebSocket脚本处理。当消息留在队列中等待脚本处理它们时,没有什么可以阻止套接字读取更多数据


您可以在WebSocket中实现的唯一真正的流控制是显式的。当消息到达时,发回一条消息以确认它。在发送下一条消息之前,让服务器等待接收该ack。

您可以对WebSocket连接进行流量控制(基于TCP背压自适应)。这里有两个链接可以帮助您入门:


披露:我是Autobahn的原始作者,为Tavendo工作。

现在可以在WebSocket中拥有流。Chrome78将附带支持背压的新WebSocketStream API

以下是一段引自:

WebSocket API为RFC6455提供了一个JavaScript接口 WebSocket协议。虽然它发挥了很好的作用,但从一个角度来看却很尴尬 人类工效学的观点和缺失的重要特征 背压。WebSocketStream API的目的是解决 这些缺陷是通过将streams与WebSocket API集成实现的

当前无法对接收到的消息应用背压 使用WebSocket API。当消息到达的速度超过页面所能到达的速度时 处理它们时,渲染过程将填充内存缓冲区 这些消息由于100%的CPU使用率或两者兼而有之而变得无响应

对发送的消息应用背压是可能的,但涉及 轮询bufferedAmount属性,该属性效率低下且 无能的

不幸的是,这是一个只使用Chrome的API,并且没有web标准 在撰写本文时

有关更多信息,请参阅:


为什么任务需要异步?如果你让它们同步,你就解决了问题。相反,如果它们是异步的,TCP连接也会有同样的问题。并非所有JS API都有同步变体。我也不希望我的应用程序因为我想限制图像的接收而没有响应。对我来说,这与其他API无关,而是web应用程序无法告诉浏览器不要接受这么多数据。如果我正确理解了链接信息,当你意识到客户端的消费速度低于服务器的生产速度时,你会暂停在服务器上发送。我认为,按照我最初的帖子,在浏览器中使用客户端时,出现这种情况的唯一方法是:网络传输数据的速率低于服务器生成数据的速率。对于浏览器中的大带宽客户端,似乎无法对服务器施加反压力。您知道一种施加客户端控制的反压力的方法吗?(如果客户端同步读取会发生什么情况)和:如果您不使用浏览器JS,而服务器继续发送,我预计会出现服务器上的TCP反压力,因为无论是内核还是浏览器WS-impl。将无限地缓冲传入的数据。不过我自己没有试过。
bufferedamount
的工作方向正好相反。在我的设置中,它允许webapp不会压倒服务器。这是好的,需要的,但不是我想要的。我的问题在于“不消费”部分。我不知道如何告诉浏览器“我目前没有消费”。内核不会隐式地缓冲,这是背压所需要的。至少Chrome是隐式缓冲的。当我在调试器中停止JS代码时,Chrome会继续从WS中读取,不会产生反压力,Chrome的内存使用率会飙升。是的,这是一个问题。浏览器中的WS-API需要让应用程序能够调整上下水印,控制浏览器WS实现对传入数据的缓冲量。如果达到高水位线,则浏览器提示。停止从套接字读取。TCP压力增大。服务器停止发送。等等。您可能希望将其加入IETF Hybi列表和/或WHATWG。或使用浏览器vendo的文件错误