【问题标题】:WebSocket frame fragmentation in an APIAPI 中的 WebSocket 帧碎片
【发布时间】:2015-07-28 17:30:51
【问题描述】:

在客户端 API 中公开 WebSocket 碎片是否有任何价值?

阅读 RFC 6455,我确信非连续帧并不能保证您在语义方面的任何事情。不应依赖帧边界。这太冒险了。规范明确解决了这个问题:

Unless specified otherwise by an extension, frames have no semantic
meaning.  An intermediary might coalesce and/or split frames, if no
extensions were negotiated by the client and the server or if some
extensions were negotiated, but the intermediary understood all the
extensions negotiated and knows how to coalesce and/or split frames
in the presence of these extensions.  One implication of this is that
in absence of extensions, senders and receivers must not depend on
the presence of specific frame boundaries.

因此,接收到二进制或文本类型的非连续帧并不意味着它是从通道另一端发送的原子且有意义的东西。同样,连续帧序列并不意味着合并它们会产生有意义的消息。而更令人不安的是, 单个非连续类型的帧可能是合并许多其他帧的结果。

总而言之,通过 WebSocket 发送的字节组几乎可以以任何方式重新组合,因为字节顺序是相同的(这当然是在没有扩展的情况下)。

如果是这样,那么引入这个概念是否有用?也许最好将其隐藏为实现细节?我想知道 WebSocket 用户是否发现它在 Netty、Jetty、Grizzly 等产品中很有用。谢谢。

【问题讨论】:

    标签: websocket jetty netty grizzly


    【解决方案1】:

    碎片化不是任何事物的界限。

    这只是实现基于内存、websocket扩展、性能等处理自身的一种方式。

    一个典型的场景是客户端发送文本,该文本通过 permessage-deflate 扩展,它将根据其 deflate 算法内存配置压缩并生成片段,将这些片段写入远程端点,因为它有一个缓冲区要写入的压缩数据(某些实现仅在缓冲区已满或消息已收到其最后一个字节时才写入)

    虽然在 API 中公开了对片段的访问(Jetty 有 2 个核心 websocket API,都支持片段访问),但它真的只对那些想要对流应用程序进行较低级别控制的人有用。 (想想你想要通过质量调整流式传输的视频/voip,如果需要,删除数据,不要写得太快等等......)

    【讨论】:

    • 我想知道 WebSocket API 客户端是否真的理解这一点。因为它的实际意思是,如果不是流式传输,最好使用 WebSocket 上的一些子协议将流划分为有意义的块(例如 RPC 调用、文本消息等),否则每次收到某些东西时,他们都会在不知不觉中掷骰子.我想并不总是可以使用黑客来说服服务器使用一些未知的随机命名的扩展名,这将有效地禁止更改框架的边界。
    • 实际上,假设帧边界无法更改,则没有构建任何 websocket 实现、websocket 扩展或 websocket 代理。 (业界用于验证 websocket 实现测试的高速公路测试套件)
    • 我想知道 WebSocket 基础设施中是否有代码将两个连续的非连续帧 f1f2 合并到 f12 中。对于那些依赖边界的最终用户来说,这可能是一个很大的惊喜。
    【解决方案2】:

    RFC 中关于未分段消息似乎有些含糊不清,它们可以任意拆分或组合。但是,在故意将消息作为多个片段(总共 X 字节)发送的情况下,是否允许中介以返回序列中不同数量(而不是 X)字节的方式拆分其中一些帧?我认为这是不允许的,并且碎片化在这方面具有一定的价值。这只是阅读 RFC,而不是查看实际实现。

    一条消息的片段不得在 另一条消息的片段,除非已扩展 协商,可以解释交织。

    在我看来,这意味着除非已经协商了允许它的扩展,否则来自不同消息的片段不能交错,这意味着虽然可以更改片段的数量,但字节的确切数量(以及字节本身)不可能。

    【讨论】:

    【解决方案3】:

    应该支持控制分片;我们有一个 C# 程序,它有意将大型 WebSocket 消息拆分为小片段,以便接收数据的小型嵌入式处理器一次可以处理小块。相反,它完全合并为一个消耗大部分可用内存的大块。 我们不确定合并发生在哪里。也许是 C# 库。

    【讨论】:

      猜你喜欢
      • 2016-02-26
      • 1970-01-01
      • 1970-01-01
      • 2021-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 2013-05-11
      相关资源
      最近更新 更多