websocket 是基于流还是基于包的协议?

Posted

技术标签:

【中文标题】websocket 是基于流还是基于包的协议?【英文标题】:Is websocket a stream-based or package-based protocol? 【发布时间】:2014-01-28 05:41:30 【问题描述】:

想象一下,我有服务器和客户端通过 WebSocket 进行通信。每次发送另一块数据。不同的块可能有不同的长度。

我可以保证,如果服务器在一次调用中发送块,那么客户端将在一次message 回调中接收它,反之亦然?即,WebSocket 是否具有嵌入的“打包”功能,所以我不必关心我的数据在传输过程中是否在多个回调中拆分?

【问题讨论】:

***.com/q/21024173/632951 , ***.com/a/13011241/632951 【参考方案1】:

WebSocket 是一种基于消息的协议,因此如果您发送一个数据块作为 WebSocket 消息的有效负载,对等方将收到一个单独的 WebSocket 消息,其中该数据块作为有效负载。

【讨论】:

我有兴趣在 2022 年左右在 Firefox 和 Chrome 中具体确认这种行为。碰巧知道吗? 是的,仍然是这样,因为任何 javascript 可用的浏览器中的 API 仍然相同,并且该 API 是基于 WebSocket 消息的,您用于观察 WebSocket 连接的 JavaScript 回调会按 - websocket 消息。没有 API(据我所知)可以获取单个 WebSocket 帧、单个 TCP/TLS 段或单个 IP 数据包。【参考方案2】:

理论上,WebSocket 协议是一种基于消息的协议。但是,请记住...

WebSocket 消息由一个或多个帧组成。 帧可以是完整的帧,也可以是分段的帧。 消息本身在协议中没有内置任何长度指示,只有帧有。 帧的有效负载长度最多可达 9,223,372,036,854,775,807 字节(因为协议允许使用 63 位长度指示符)。 分段的主要目的是允许在消息启动时发送大小未知的消息,而无需缓冲该消息。

所以...

单个 WebSocket“消息”可以包含无限数量的 9,223,372,036,854,775,807 字节片段。

这可能会使实现难以始终通过其 API 向您传递完整的消息...

因此,在一般情况下,您的问题的答案是 WebSocket 协议是基于消息的协议,您不必手动构建消息。您用于使用该协议的 API 可能具有适当的消息大小限制(以允许它保证消息作为单个块传送),或者可能提供流接口以允许无限大小的消息。

我在标准化过程中对此大喊大叫here。

【讨论】:

陈词滥调(大约 2011 年),大多数观点都没有实际意义,无效,或者现在在 websocket 的各种实际实现中得到解决。 好吧,我认为我们同意不同意,除非您喜欢评论相关博客文章并指出它现在不正确的地方;然后我们可以讨论。实现 CAN 和 DO 提出了自己的解决方法(例如消息大小限制)这一事实并没有减损协议规范允许上述行为的事实,恕我直言,这是不幸的,应该/当时本来可以处理的。 我想所有参与这里讨论的都是我所谓的网络和 WebSocket 专家;)但我想向其他读者指出一件事:我想值得区分 API协议。 WebSocket API 可以在不同级别公开 WebSocket:每条消息、每帧或流。即使使用流式 API,实现也可以暴露消息边界。在任何情况下,WebSocket 协议本身都是基于消息(和帧)的。它需要保留消息边界 - 但不是帧边界。 确实如此。然而,最初的问题通过询问实现如何将消息传递给用户代码而使水变得有点混乱。

以上是关于websocket 是基于流还是基于包的协议?的主要内容,如果未能解决你的问题,请参考以下文章

python之WebSocket协议

socket.io websocket

websocket的理解及实例应用

使用python 多进程进行基于websocket 的实时视频流处理

使用python 多进程进行基于websocket 的实时视频流处理

基于WebSocket协议的iOS端即时聊天