提问人:yeputons 提问时间:1/9/2014 更新时间:1/10/2014 访问量:5819
websocket 是基于流还是基于包的协议?
Is websocket a stream-based or package-based protocol?
问:
想象一下,我有服务器和客户端通过 WebSocket 进行通信。每次发送另一个数据块。不同的块可能具有不同的长度。
我是否可以保证,如果服务器在一次调用中发送块,那么客户端将在一次回调中收到它,反之亦然?也就是说,WebSocket 是否具有嵌入式“打包”功能,因此我不必担心我的数据在传输过程中是否被拆分为多个回调?message
答:
10赞
oberstet
1/9/2014
#1
WebSocket 是一种基于消息的协议,因此,如果您发送一个数据块作为 WebSocket 消息的有效负载,则对等方将收到一个单独的 WebSocket 消息,其中包含该数据块作为有效负载。
评论
0赞
Todd Freed
2/2/2022
我对 2022 年左右在 Firefox 和 Chrome 中对这种行为的具体确认感兴趣。碰巧知道吗?
1赞
oberstet
2/3/2022
是的,仍然如此,因为任何 JavaScript 可用的浏览器中的 API 仍然是相同的,并且该 API 是基于 WebSocket 消息的,因此您用于观察 WebSocket 连接的 JavaScript 回调会触发每个 websocket-message。据我所知,没有 API 可以获取单个 WebSocket 帧、单个 TCP/TLS 段或单个 IP 数据包。
15赞
Len Holgate
1/10/2014
#2
从理论上讲,WebSocket 协议呈现出一种基于消息的协议。但是,请记住......
- WebSocket 消息由一个或多个帧组成。
- 帧可以是完整的帧,也可以是碎片帧。
- 消息本身在协议中没有内置任何长度指示,只有帧有。
- 帧的有效负载长度最高可达 9,223,372,036,854,775,807 字节(由于协议允许使用 63 位长度指示器)。
- 分段的主要目的是允许在消息启动时发送未知大小的消息,而无需缓冲该消息。
所以。。。
单个 WebSocket“消息”可以包含无限数量的 9,223,372,036,854,775,807 字节片段。
这可能会使实现难以始终通过其 API 向您传递完整的消息......
因此,在一般情况下,您的问题的答案是 WebSocket 协议是基于消息的协议,您不必手动构建消息。用于使用该协议的 API 可能具有消息大小限制(以允许它保证将消息作为单个块传递),或者可能提供流式处理接口以允许无限大小的消息。
我在这里的标准化过程中对此大发雷霆。
评论
1赞
Joakim Erdfelt
1/10/2014
Old Rant(大约 2011 年),大多数观点都是没有意义的、无效的,或者现在在 WebSocket 的各种实际实现中得到解决。
1赞
Len Holgate
1/10/2014
好吧,我认为我们会同意不同意,除非你想对有问题的博客文章发表评论并指出它现在是不正确的;然后我们可以讨论。实现 CAN 和 DO 提出了自己的解决方法(例如消息大小限制)这一事实并没有减损协议规范允许上述行为的事实,恕我直言,这是不幸的,应该/可以在当时处理。
0赞
oberstet
1/10/2014
我想所有参与讨论的人都是我所说的网络和 WebSocket 专家;但我确实想为其他读者指出一件事:我想有必要区分 API 和协议。WebSocket API 可以在不同级别公开 WebSocket:每条消息、每帧或流式处理。即使使用流式处理 API,实现也可以公开消息边界。无论如何,WebSocket 协议本身都是基于消息(和帧)的。它要求保留消息边界,但不是帧边界。
0赞
Len Holgate
1/10/2014
事实上。然而,最初的问题通过询问实现如何将消息传递给用户代码而使水变得有点混乱。
评论