You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 05:35:21