Skip to content

NACT Framing ​

NACT 会把一个 NACP 包分片成一个或多个 NACT 帧。

无论是否需要分片,每一帧NACT都会额外添加长度为 32 Bytes 的帧头。

NACT 帧头 ​

Offset+0+1+2+3+4+5+6+7+8+9+A+B+C+D+E+F
0x00msgId
16 B
0x10offset
4 B
totalSize
4 B
thisFrameSize
4 B
blank
2 B
magic
1 B
version
1 B

帧体紧跟在 32B 帧头后,从 0x20 开始,长度为 thisFrameSize - 32。

Offset长度字段编码v1 值含义
016msgId16 bytes-同一 NACP 包的所有帧相同
164offsetuint32, BE—本帧在所属 NACP 包中的起始字节
204totalSizeuint32, BE—所属 NACP 包的总长度
244thisFrameSizeuint32, BE—本帧总长,含这 32B 帧头,故 bodyLen = thisFrameSize - 32。
282blankuint16, BE0x0000预留给未来的指示位
301magicuint80xCF魔数
311versionuint80x01NACT Message版本

DANGER

feat: NACT对单帧和单包的大小限制分别为2GB和4GB

由于totalSize长度仅4Bytes,因此最大的长度只有2^(4*8)-1 Bytes,即约4GB。

这个数字其实是原先Node20对Buffer的最大限制,尽管在Node24中上限被提高到了8PB。

此外 thisFrameSize 超过 MAX_FRAME_SIZE(默认 2 GiB)则会出现 frame-too-large错误。

本特性在 (NASDK v1.0.4,NACT v1) 仍存在。未来可能会通过增加头部长度、缩短msgID或利用Blank字段提升长度限制。但是至少最近一段时间不会考虑修改NACT

分帧与重组 ​

NACP 包超过分片阈值时,NACT 会把它分片成多个帧依次发送。

分片阈值来自 TransportSpec.nact.chunkSize,省略时使用当前 Provider 声明的推荐默认值。

分片的目的是为了穿透物理传输中间层的单次提交上限(如部分CDN限制100MB上传之类的),同时进一步降低发送端合并产生的内存峰值。

TIP

NACP默认分片大小是100MB,但UnixSocket默认不分片。

Details

1GB payload 实测:

provider分帧wire (ms)接收端内存峰值
unix一帧6651024 MB
unix100MB × 116681024 MB
tcp一帧7341024 MB
tcp100MB × 116671024 MB
ws一帧27843027 MB
ws100MB × 1139311147 MB

Q:这里为什么会x11

A:因为这一组测试把 chunkSize 设为 100MB,NACT 保证加上帧头后每一帧不超过 100MB,所以每帧只装 100MB-32B 的数据,余下的 320B 单独成一帧(32B 帧头 + 320B)。

Released under the MIT License.