当前位置: 首页 > 面试题库 >

分块WebSocket传输

韶浩皛
2023-03-14
问题内容

由于我在更常规的基础上使用WebSocket连接,因此我对事物的工作原理很感兴趣。因此,我花了一段时间研究无休止的规范文档,但到目前为止,我还没有真正找到有关
分块传输流本身的 任何信息。

WebSocket协议将其称为 数据帧 (描述了纯数据流,因此也称为 非控制帧
)。据我了解,规范没有定义最大长度,也没有定义MTU(最大传输单位)值,这反过来意味着单个WebSocket数据帧可以通过spec(!)包含无限数量的数据。
(如果我在这里错了,请纠正我,我仍然是这个的学生)。

阅读完这些内容后,我立即设置了我的小型 Node WebSocket服务器。由于我拥有 丰富的Ajax
历史(同时在流媒体和Comet上),因此我最初的期望是:“ 在传输数据时必须有某种交互方式来读取数据 ”。但是我错了,不是吗?

我刚开始时只有 4kb 的数据。

服务器

testSocket.emit( 'data', new Array( 4096 ).join( 'X' ) );

就像预期的那样,它作为一个数据块到达客户端

客户

wsInstance.onmessage = function( data ) {
    console.log( data.length ); // 4095
};

所以我增加了有效负载,实际上我又在期待,在某个时候,客户端onmessage处理程序将重复触发,有效地分块传输。但是令我震惊的是,它从未发生过(
node-server ,在 firefoxchromesafari 客户端上进行了测试)。我最大的有效负载是 80
MB

testSocket.emit( 'data', new Array( 1024*1024*80 ).join( 'X' ) );

它仍然到达客户端上的一个大数据块中。当然,即使您的连接很好,也要花一些时间。这里的问题是

  • 是否有可能像XHR readyState3模式那样对那些流进行分块
  • 一个ws数据帧有大小限制 吗?
  • websocket是否不应该传输这么大的有效载荷? (这让我再次想知道为什么没有定义的最大尺寸)

我可能仍然从WebSockets的错误角度看待,可能不存在发送大量数据的需求,并且您应该在发送之前自己逻辑上对数据进行分块/拆分吗?


问题答案:

首先,您需要在 浏览器中 区分WebSocket 协议 和WebSocket API 。 __

WebSocket协议的帧大小限制为2 ^ 63个八位位组,但是WebSocket消息可以由无限数量的帧组成。

浏览器中的WebSocket
API不会公开基于框架的API或流式API,而只会公开基于消息的API。传入消息的有效负载始终会被完全缓冲(在浏览器的WebSocket实现中),然后再将其提供给JavaScript。

其他WebSocket实现的API可以提供对通过WebSocket协议传输的有效负载的基于帧或流的访问。例如,AutobahnPython就是这样做的。您可以在这里的示例中阅读更多内容https://github.com/tavendo/AutobahnPython/tree/master/examples/twisted/websocket/streaming。

披露:我是高速公路的原始作者,并且为Tavendo工作。

更多注意事项:

只要浏览器JS WebSocket API中没有框架/流API,您就只能接收/发送完整的WS消息。

单个(普通)WebSocket连接无法交错多个消息的有效负载。因此,例如,如果您使用大消息,则这些消息将按顺序传递,并且当大消息仍在运行时,您将无法在两次消息之间发送小消息。

WebSocket即将推出(扩展是扩展协议的内置机制):WebSocket复用。这允许在单个基础TCP连接上具有多个(逻辑)WebSocket连接,这具有多个优点。

另请注意:您可以从一个单一的JS / HTML页面打开多个WS连接(在不同的底层技术合作计划),以一台目标服务器 今天

另请注意:您可以在应用程序层中“分块”:以较小的WS消息发送您的内容,然后重新组装。

我同意,在理想的世界中,您将在浏览器中使用消息/框架/流API以及WebSocket复用。这将提供所有的功能和便利。



 类似资料:
  • 问题内容: 该代码是否有效的HTTP / 1.1? 我认为我在这里违反HTTP / 1.1?文本文件似乎确实可以正常工作,但这可能是偶然的。我的标题是“ 200 OK”还是需要为“ 100”?一个头足够吗? 问题答案: 如果要进行分块传输编码,则实际上需要设置该标头: 您可以从google返回的标头中看到该标头,该标头会对主页以及最可能的其他页面进行分块传输: 编辑 Yikes,读起来太复杂了:

  • 除了通过putObject接口上传文件到OSS以外,OSS还提供了另外一种上传模式 —— Multipart Upload。用户可以在如下的应用场景内(但不仅限于此),使用Multipart Upload上传模式,如: 需要支持断点上传。 上传超过100MB大小的文件。 网络条件较差,和OSS的服务器之间的链接经常断开。 需要流式地上传文件。 上传文件之前,无法确定上传文件的大小。 下面我们将一步

  • 除了通过putObject接口上传文件到OSS以外,OSS还提供了另外一种上传模式 —— Multipart Upload。用户可以在如下的应用场景内(但不仅限于此),使用Multipart Upload上传模式,如: 需要支持断点上传。 上传超过100MB大小的文件。 网络条件较差,和OSS的服务器之间的链接经常断开。 需要流式地上传文件。 上传文件之前,无法确定上传文件的大小。 下面我们将一步

  • 我们正在尝试让Flask web服务正常工作,但是流式帖子出现了一些问题,例如,当标题包含传输编码时:chunked。 似乎默认的flask不支持HTTP 1.1。这有什么办法吗? 我们正在运行此命令: 违反此代码: 以下是旋度输出: 这是Flask服务器的输出:

  • 问题内容: 我正在尝试使用html5的File API批量上传文件,然后在php的服务器端重新组装它。我正在上传视频,但是当我在服务器端合并文件时,文件大小增加了,并且变成了无效文件。请注意,以下html5代码仅适用于chrome浏览器。在Chrome 9中进行了测试,因为它使用了文件API的slice函数。有人可以指导我吗?谢谢 HTML来源 问题答案: Slice Function接受第二个参

  • 我正在尝试以分块模式发送数据。正确设置所有标题,并相应地对数据进行编码。浏览器将我的响应识别为分块响应,接受标题并开始接收数据。 我希望浏览器会更新每个接收到的区块的页面,而不是等到所有区块都被接收,然后显示它们。这是预期的行为吗? 我希望看到每个块在收到后立即显示。使用时,每个块在收到后立即显示。为什么GUI浏览器不会发生同样的情况?他们是否在使用某种缓冲/缓存? 我将标头设置为,所以不确定它是