11

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

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

客户端是否会使用传统的 TCP 连接,它会停止从连接中读取。这将导致接收缓冲区被填满,接收窗口被关闭,并最终暂停在服务器上发送图像。一旦客户端开始读取,接收缓冲区将清空,接收窗口将打开,服务器继续传输。每次我的服务器开始发送图像时,它都会选择最新鲜的图像。这种选择最新鲜的行为与 TCP 的流量控制一起确保了在许多情况下的合理行为。

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

4

3 回答 3

7

现在可以在 WebSocket 中使用流。Chrome 78 将附带一个新的 WebSocketStream API,它支持背压。

这是来自Chrome Platform Status的引述:

WebSocket API 为 RFC6455 WebSocket 协议提供了一个 JavaScript 接口。虽然效果很好,但从人体工程学的角度来看它很尴尬,并且缺少背压的重要特征。WebSocketStream API 的目的是通过将流与 WebSocket API 集成来解决这些缺陷。

目前无法使用 WebSocket API 对接收到的消息应用背压。当消息到达的速度快于页面可以处理的速度时,渲染进程要么填满缓冲这些消息的内存,要么由于 100% 的 CPU 使用率而变得无响应,或者两者兼而有之。

对发送的消息应用背压是可能的,但涉及轮询 bufferedAmount 属性,这是低效且不符合人体工程学的。

不幸的是,这是一个仅限 Chrome 的 API,在撰写本文时还没有网络标准。

有关更多信息,请参阅:

于 2019-09-20T13:43:29.293 回答
5

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

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

于 2013-10-16T22:20:28.283 回答
2

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

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

于 2013-10-17T08:29:38.550 回答