Javascript 分块式网箱传动

Javascript 分块式网箱传动,javascript,node.js,websocket,specifications,Javascript,Node.js,Websocket,Specifications,因为我在更常规的基础上使用WebSocket连接,所以我对引擎盖下的工作方式很感兴趣。因此,我在无尽的规范文档中钻研了一段时间,但到目前为止,我还没有找到任何关于传输流本身分块的信息 WebSocket协议将其称为数据帧(它描述纯数据流,因此也称为非控制帧)。就我对规范的理解而言,没有定义的最大长度和定义的MTU(最大传输单位)值,这反过来意味着单个WebSocket数据帧可能包含无限量的数据(根据规范(!),如果我在这里错了,请纠正我,我仍然是这方面的学生) 读完这篇文章后,我立即设置了我的小

因为我在更常规的基础上使用WebSocket连接,所以我对引擎盖下的工作方式很感兴趣。因此,我在无尽的规范文档中钻研了一段时间,但到目前为止,我还没有找到任何关于传输流本身分块的信息

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

读完这篇文章后,我立即设置了我的小节点WebSocket服务器。由于我有很强的Ajax历史(同样在流媒体和Comet方面),我最初的期望是“在传输数据时必须有某种交互模式来读取数据”。但我错了,不是吗

我一开始很小,有4kb的数据

服务器

testSocket.emit( 'data', new Array( 4096 ).join( 'X' ) );
正如预期的那样,它作为一个数据块到达客户机

客户端

wsInstance.onmessage = function( data ) {
    console.log( data.length ); // 4095
};
所以我增加了有效负载,实际上我又在期待,在某个时刻,客户端
onmessage
处理程序将重复启动,有效地阻塞传输。但令我震惊的是,它从未发生过(节点服务器,在firefox、chrome和safari客户端上进行了测试)。我最大的有效负载是80MB

testSocket.emit( 'data', new Array( 1024*1024*80 ).join( 'X' ) );
它仍然以一个大数据块的形式出现在客户机上。当然,这需要一段时间,即使你有一个很好的连接。这里的问题是

  • 与XHR readyState3模式类似,是否有可能将这些流分块
  • 单个ws数据帧是否有大小限制
  • WebSocket不应该传输如此大的有效负载吗?(这会让我再次疑惑,为什么没有定义最大尺寸)

我可能仍然从错误的角度看待WebSocket,可能只是不需要发送大量数据,在发送之前,您应该自己逻辑地分块/拆分任何数据?

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

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

浏览器中的WebSocket API不公开基于帧或流的API,而只公开基于消息的API。传入消息的负载在提供给JavaScript之前总是被完全缓冲(在浏览器的WebSocket实现中)

其他WebSocket实现的API可以提供对通过WebSocket协议传输的有效负载的基于帧或流的访问。比如说,他有。您可以在这里的示例中阅读更多内容

披露:我是《高速公路》的原作者,为塔文多工作

更多注意事项:

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

单个(普通)WebSocket连接无法交错多条消息的有效负载。因此,也就是说,如果您使用大消息,这些消息会按顺序发送,而当大消息仍在运行时,您将无法在其间发送小消息

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

另外请注意:现在,您可以从单个JS/HTML页面打开多个WS连接(通过不同的底层TCP)到单个目标服务器

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

我同意,在一个理想的世界中,您应该在浏览器中使用消息/帧/流API以及WebSocket多路复用。这将给所有的权力和便利

:

这就是WebSocket协议所提供的:[…]是HTTP轮询的替代方法,用于从网页到远程服务器的双向通信

如上所述,WebSocket用于网页和服务器之间的通信。请注意网页和web浏览器之间的区别。使用的例子是浏览器游戏和聊天应用程序,它们可以更改许多小消息

如果您想在一条消息中发送多个MB,我认为您没有按照预期的方式使用WebSocket。如果要传输文件,请使用一个普通的旧Http请求,并以
Content-Disposition
响应,让浏览器下载文件

因此,如果您解释为什么要发送如此大量的数据,也许有人可以帮助您想出一个比使用WebSocket更优雅的解决方案

此外,客户机或服务器可能会拒绝太大的消息(尽管没有明确说明如何拒绝):

:

具有特定于实现和/或平台的实现 之后有关帧大小或消息总大小的限制 从多个框架重新组装时必须保护自身免受 超过这些限制。(例如,恶意端点可以尝试 通过以下方式耗尽对等方的内存或发起拒绝服务攻击: 发送单个大帧(例如大小为2**60)或通过发送 一长串的小帧,它们是碎片图像的一部分 这样的实现应该对帧进行限制 从多个服务器重新组装后的大小和总消息大小 框架


因此,如果我的快速计算是正确的,那就是大约83 TB的帧大小,在本例中几乎等于无穷大。然而,没有(浏览器)API允许拦截传输流?听起来是w