PeerJS文件传输指南:ArrayBuffer与Blob大文件分块传输避坑清单
2026/9/19 5:09:22 网站建设 项目流程

PeerJS文件传输指南:ArrayBuffer与Blob大文件分块传输避坑清单

【免费下载链接】peerjsSimple peer-to-peer with WebRTC.项目地址: https://gitcode.com/gh_mirrors/pe/peerjs

PeerJS 是基于 WebRTC 的开源点对点库,一行send()就能在两台浏览器之间传输数据,但大文件传输恰恰是新手最容易踩坑的地方:ArrayBuffer 何时被分块?Blob 和 File 到达对端会变成什么类型?8MB 缓冲背压又是怎么回事?本文结合 PeerJS 源码与端到端测试用例,给出一份完整的PeerJS 文件传输避坑清单,帮你一次讲清 ArrayBuffer 与 Blob 的分块传输机制。

先看懂:PeerJS 文件传输的 3 层管线

在动手之前,先知道一条conn.send(bigFile)背后发生了什么。PeerJS 的数据连接由三层机制组成:

层级职责关键阈值源码位置
序列化层把 ArrayBuffer / Blob / JSON 等数据编码为二进制BinaryPack.ts
分块层超大的包自动切成小块逐片发送16300 字节binaryPackChunker.ts
背压层发送队列积压时暂停发送,防止内存爆炸8 MBDataConnection.ts

理解这 3 层,下面所有的坑都能迎刃而解。

快速上手:3 步发送一个文件

PeerJS 通过npm install peerjs安装,核心用法极简——建立数据连接、等open事件、调用send()

import { Peer } from "peerjs"; const peer = new Peer("my-id"); // 发送端:连接并发送 File peer.on("open", () => { const conn = peer.connect("another-peers-id"); conn.on("open", () => { const file = new File([arrayBuffer], "report.bin", { type: "application/octet-stream" }); conn.send(file); // 超大文件会自动分块,无需手动处理 }); }); // 接收端 peer.on("connection", (conn) => { conn.on("data", (data) => { console.log(data); // 注意:这里收到的是 ArrayBuffer,不是 Blob }); });

更多基础用法可参考 README.md 与交互式演示页 serialization.html。

ArrayBuffer 分块传输原理:为什么是 16300 字节?

很多教程说"分块大小设为 60000 字节",但 PeerJS 源码里写的是16300,这不是笔误:

readonly chunkedMTU = 16300; // The original 60000 bytes setting does not work // when sending data from Firefox to Chrome...

(见 binaryPackChunker.ts)

原始 60000 字节设置会导致 Firefox 向 Chrome 发送数据时在 16384 字节处被"截断",所以 PeerJS 选择了安全的 16300 字节作为分块 MTU。

分块协议也很简单,每片数据都携带元信息(BinaryPack.ts):

  • __peerData:分块组的唯一 ID
  • n:当前分块的序号
  • total:总分块数
  • data:本片的二进制内容

接收端收齐所有分块后,通过 concatArrayBuffers 自动拼装回完整的 ArrayBuffer,再触发data事件。你无需自己写任何拼装代码——只要不手动干预,完整性由 PeerJS 保证。

Blob 与 File 的正确用法:接收端拿到的是 ArrayBuffer

这是最反直觉的一点:PeerJS 官方端到端测试中,发送Blob/File对端收到的是 ArrayBuffer,而不是 Blob:

  • blobs.js:dataConnection.send(new Blob([json]))发送 Blob
  • files.js:dataConnection.send(new File(...))发送文件
  • 两者断言接收到的都是ArrayBuffer(files.js)

也就是说,如果接收方想还原成文件下载链接,需要自己执行一步:

const blob = new Blob([data], { type: "application/octet-stream" }); const url = URL.createObjectURL(blob);

避坑清单:7 个高频错误对照表

#现象正确做法
1open事件前调用send()触发NotOpenYet错误,消息直接丢弃先监听open再发送(见 DataConnection.ts)
2自己手动把大文件切成小片发送与内置分块器叠加,接收端语义错乱直接send()整个 ArrayBuffer / Blob,交给 BinaryPackChunker
3循环高频send()大对象发送队列超过 8MB 后触发背压,数据被挂起、延迟飙升控制发送节奏,利用conn.bufferSize观察积压(BufferedConnection.ts)
4跨浏览器传输时自行改 MTU 为 60000Firefox → Chrome 方向数据在 16384 字节处截断保持默认的 16300 字节分块阈值
5以为接收到的还是 Blob / Fileinstanceof Blob判断失败,后续处理报 undefined按 ArrayBuffer 接收,必要时自行new Blob([data])
6直接close()想"发完再断"已缓冲未发的数据被清空丢弃close({ flush: true })先冲刷缓冲区再关闭(BufferedConnection.ts)
7大文件用 JSON 序列化传输体积膨胀严重、性能差默认使用 binary(BinaryPack)序列化,文本数据也可转 ArrayBuffer 发送

其中第 3 条值得展开:当dataChannel.bufferedAmount超过 8MB(MAX_BUFFERED_AMOUNT,见 DataConnection.ts)时,PeerJS 会暂停发送并等 50ms 后重试(BufferedConnection.ts)。这是保护机制而非故障——但如果你疯狂调用send(),页面会长时间卡在这个"憋气"状态。

验证你的传输:官方端到端测试矩阵

不确定自己传的数据类型是否被支持?PeerJS 内置了一整套数据通道序列化测试,覆盖了几乎所有常见场景:

  • 二进制类:arraybuffers.js、Uint8Array.js、Int32Array.js、typed_array_view.js
  • 文件类:blobs.js、files.js
  • 大字符串:long_string.js(重复 10 万次的长字符串)
  • 测试数据源:data.js、commit_data.js
  • 测试流程编排:serializationTest.ts

对照这份矩阵自查:你传的数据类型在测试里能找到对应文件,就放心传。

总结

PeerJS 把文件传输最脏的活——序列化、分块、拼装、背压——都封装好了。新手要记住的只有三件事:

  1. open再发送,别提前抢跑;
  2. 别手动分块,16300 字节的自动分块器已经处理了跨浏览器兼容;
  3. 接收端按 ArrayBuffer 处理,Blob / File 不会以原类型到达对端。

照这份避坑清单走,PeerJS 的 WebRTC 点对点大文件传输会变得和console.log一样省心。

【免费下载链接】peerjsSimple peer-to-peer with WebRTC.项目地址: https://gitcode.com/gh_mirrors/pe/peerjs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询