因为我在更常规的基础上使用WebSocket连接,所以我对引擎盖下的工作方式很感兴趣.所以我在无尽的规范文档中挖掘了一段时间,但到目前为止,我真的找不到关于chunking the transmission stream itself的任何东西.

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

读完这篇文章后,我立即安装了我的小型Node WebSocket服务器.因为我有一个强大的Ajax历史(也在流媒体和Comet上),我最初的期望是"there must be some kind of interactive mode for reading data while it is transfered".但我错了,不是吗?

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

server

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

正如预期的那样,它作为一个数据块到达客户机

client

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

所以我增加了有效载荷,实际上我又在期待,在某个时刻,客户端onmessage处理器会重复emits ,有效地拦截传输.但令我震惊的是,它从未发生过(node-server,在firefoxchromesafari客户端上进行了测试).我最大的有效载荷是80 MB

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

它仍然以一个 Big Data 块的形式出现在客户机上.当然,即使你的人脉很好,这也需要一段时间.这里的问题是

  • is there any possiblity to chunk those streams, similar to the XHR readyState3 mode ?
  • is there any size limit for a single ws data-frame ?
  • are websockets not supposed to transfer such large payloads? (which would make me wonder again why there isn't a defined max-size)

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

推荐答案

首先,需要区分browsers中的WebSocket protocol和WebSocket API.

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

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

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

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

更多注意事项:

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

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

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

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

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

我同意,在一个理想的世界里,浏览器中应该有消息/帧/流式API,再加上WebSocket多路复用.这将提供所有的力量和便利.

Node.js相关问答推荐

使用NodeJS在S3上传文件时的格式问题

正在try 使用Azure Function App上载文件时未上载文件(&Q;)

Express无法发布

如何呈现ejs.renderFile中包含的子模板?

无法使用NPM安装REDUX和DATEPPICER

MongoDB的方面查询的Postgres类似功能

在对象的嵌套数组中使用$lookup,创建多个记录作为响应,mongodb

我需要聚合两个 MongoDB 集合

将代码转换为 ES6 Discord.js 的问题

为什么我的 Cypress Post 请求的请求正文是空的?

为什么当我try req.logout() 时出现此错误?

如何在 mongoDB 中进行全动态搜索?

Socket IOFlutter 未连接

baseurl64 缓冲区解码

eslint - vscode 的可选链接错误

node/express:使用 Forever 连续运行脚本时设置 NODE_ENV

在多个 .env 文件之间切换,例如 .env.development 和 node.js

Node.JS 中的基本 HTTP 身份验证?

`return function *(){...}` 是什么意思?

我无法全局安装 nodemon,nodemon无法识别