分块传输的WebSocket(Chunking WebSocket Transmission)

2019-07-01 17:40发布

因为我使用的是更经常基地WebSocket连接,我很感兴趣的事情引擎盖下是如何工作的。 所以我挖成一个,而无休止的规范文件,但到目前为止,我真的无法找到有关分块传输流本身什么。

WebSocket协议调用它的数据帧 (其描述了纯的数据流,所以其也被称为非控制帧 )。 据我理解规范,不存在定义的最大长度并且没有定义MTU(最大传输单元)值,这又意味着在单个的WebSocket数据帧可包含,由规范(!)中,数据的一个无限量(请纠正我,如果我错了这里,我仍然对这个学生)。

读取后,我立刻安装我的小节点的WebSocket服务器。 因为我有一个强大的Ajax历史(也流和彗星),我的期望的渊源就像,“ 必须有某种交互方式读取数据,同时它转移 ”。 但我错了,是不是我?

我开始了小,具有4KB的数据。

服务器

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

而像预计到达客户端作为一个数据块

客户

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

所以我增加了有效载荷和我实际上是又怀孕了,在某些时候,客户端onmessage处理器将屡火,effectivley分块传输。 但让我震惊,它从来没有发生过( 节点服务器 ,在Firefox,ChromeSafari的客户端测试)。 我最大有效载荷为80 MB

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

它仍然抵在客户端上的一个大的数据块。 当然,这需要一段时间,即使你有一个很好的连接。 这里的问题是

  • 有没有什么方法可行块的流,类似于XHR readyState3模式
  • 是有一个单一的WS数据帧中的任何大小限制
  • 是的WebSockets不应该转移这么大的载荷? (这让我再次纳闷为什么没有一个定义的最大尺寸)

我还是会从错误的角度去看待上的WebSockets,可能需要发送大量的数据量是不存在,你应该块/逻辑上自己发送前分裂的数据?

Answer 1:

首先,你需要WebSocket 协议浏览器中的WebSocket的API来区分。

WebSocket协议具有2 ^ 63个八位字节的帧大小限制,但一个网页套接字消息可以由无限数量的帧组成。

浏览器内的网页套接字API不公开基于帧或流API,但只有一个基于消息的API。 传入消息的有效载荷总是完全将其提供给JavaScript的前缓冲起来(在浏览器的执行的WebSocket内)。

其他的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消息的重新组装自己。

我同意,在一个理想的世界,你必须在浏览器中加WebSocket的复用消息/帧/流API。 这将使所有的权力和便利。



Answer 2:

RFC 6455第1.1节 :

这是WebSocket协议规定:[...]到HTTP轮询的替代用于双向通信从网页到远程服务器

如前所述,WebSockets的是网页和服务器之间commmunications。 请注意网页和网络浏览器之间的差异。 正在使用的例子是网页游戏和聊天应用程序,谁excange许多小消息。

如果你想发送许多MB的一个消息,我觉得你不使用的WebSockets,他们的目的的方式。 如果要传输的文件,那么这样做使用普通老式HTTP请求,回答Content-Disposition让浏览器下载文件。

所以,如果你解释你为什么要发这样的大量的数据,也许有人能帮助想出比使用的WebSockets更优雅的解决方案。

此外,客户端或服务器可以拒绝过大的消息(虽然它没有明确说明它会如何拒绝):

RFC 6455第10.4节 :

具有关于从多个帧重新组装后的帧大小或总消息大小必须保护自己免受超出这些限制implementation-和/或特定于平台的限制实现。 (例如,恶意端点可以尝试竭其对等方的存储器,或通过发送一个单一的大帧(例如,大小为2 ** 60),或通过发送小帧的长流安装拒绝服务攻击的是是一个分段消息的一部分。)从多个帧重新组装后这样的实现应该强加帧大小和总的消息大小的限制。



文章来源: Chunking WebSocket Transmission