如何使用PeerJS跟踪向WebRTC对等端发送文件的上传进度?
在PeerJS中跟踪WebRTC文件上传进度的方法
PeerJS的DataConnection本身没有内置上传进度监听,但可以通过分片发送+接收端确认+本地进度统计的方案实现可靠的上传进度跟踪。核心思路是将文件拆分为小块,逐个发送并等待接收端的确认消息,以此来统计已成功送达的数据量。
实现步骤与代码示例
发送端(跟踪上传进度)
import Peer from 'peerjs'; const peer = new Peer(peerId, { host: 'cloudbreeze-peer.onrender.com', secure: true }); peer.on('connection', (conn) => { const file = html_file_object; const chunkSize = 1024 * 1024; // 1MB分片大小,可根据网络状况调整 const totalChunks = Math.ceil(file.size / chunkSize); let sentChunks = 0; let currentChunkIndex = 0; conn.on('open', () => { // 先发送文件元数据,让接收端了解文件基本信息 conn.send({ type: 'file-meta', name: file.name, size: file.size, totalChunks: totalChunks, type: file.type }); // 监听接收端的分片确认消息 conn.on('data', (data) => { if (data.type === 'chunk-ack' && data.index === currentChunkIndex) { sentChunks++; // 计算并输出上传进度 const uploadProgress = (sentChunks / totalChunks) * 100; console.log(`上传进度: ${uploadProgress.toFixed(2)}%`); // 发送下一个分片 currentChunkIndex++; sendNextChunk(); } }); // 启动分片发送流程 sendNextChunk(); function sendNextChunk() { if (currentChunkIndex >= totalChunks) { // 所有分片发送完成,通知接收端 conn.send({ type: 'file-complete' }); return; } const start = currentChunkIndex * chunkSize; const end = Math.min(start + chunkSize, file.size); const chunk = file.slice(start, end); conn.send({ type: 'file-chunk', index: currentChunkIndex, chunk: chunk }); } }); });
接收端(发送确认消息)
import Peer from 'peerjs'; const peer = new Peer(receiverPeerId, { host: 'cloudbreeze-peer.onrender.com', secure: true }); peer.on('connection', (conn) => { let fileMeta = null; const receivedChunks = new Map(); conn.on('data', (data) => { switch (data.type) { case 'file-meta': fileMeta = data; break; case 'file-chunk': // 存储收到的分片 receivedChunks.set(data.index, data.chunk); // 向发送端发送分片确认,触发下一片发送 conn.send({ type: 'chunk-ack', index: data.index }); // 接收端可自行统计接收进度(可选) const receiveProgress = (receivedChunks.size / fileMeta.totalChunks) * 100; console.log(`接收进度: ${receiveProgress.toFixed(2)}%`); break; case 'file-complete': // 合并所有分片为完整文件 const chunksArray = Array.from(receivedChunks.values()); const blob = new Blob(chunksArray, { type: fileMeta.type }); // 示例:创建下载链接 const downloadLink = document.createElement('a'); downloadLink.href = URL.createObjectURL(blob); downloadLink.download = fileMeta.name; downloadLink.click(); URL.revokeObjectURL(downloadLink.href); break; } }); });
方案说明
- 接收端确认的必要性:PeerJS的
send方法仅负责将数据放入发送队列,无法直接获知数据是否已成功送达对等端。通过接收端的确认消息,发送端能准确统计已成功传输的分片数量,从而得到真实的上传进度。 - 分片大小可灵活调整:1MB是兼顾传输效率和重传开销的均衡选择,若网络环境较差可适当缩小分片大小,减少单次传输失败的影响。
内容的提问来源于stack exchange,提问作者Sahil Aggarwal
相关产品推荐
相关产品推荐

