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

多视频上传:socket.on监听器进度与索引关联错误修复

多视频上传时Socket进度监听关联错误的解决方案

问题核心

同时上传多个视频时,socket.on('upload-progress')和socket.on('upload-success')监听器会触发所有视频的状态更新,且监听器内的index值无法正确绑定对应视频,导致进度和ID被错误分配。

解决方案

核心思路是给每个上传任务分配唯一标识,让前后端通过这个标识关联任务,确保事件只触发对应视频的状态更新。

1. 前端代码修改

生成唯一uploadId,上传时携带该标识,监听事件时通过uploadId匹配对应视频索引,上传完成后移除监听器避免内存泄漏:

async function handleUploadLectureVideo({ files }: any, index: number) {
  const file = files[0];
  // 生成唯一上传ID(浏览器环境可用crypto.randomUUID,其他环境可自定义唯一值)
  const uploadId = crypto.randomUUID();

  socket.emit("upload-file", {
    file,
    fileMeta: {
      originalName: file.name,
    },
    name: file.name,
    uploadId, // 携带唯一标识
  });

  // 进度监听函数:仅处理当前uploadId的事件
  const handleProgress = (eventData: { uploadId: string; percentage: number }) => {
    if (eventData.uploadId === uploadId) {
      setValue(`courseLectures.${index}.uploadingProgress`, eventData.percentage);
    }
  };

  // 成功监听函数:仅处理当前uploadId的事件,完成后移除监听器
  const handleSuccess = (eventData: { uploadId: string; id: string }) => {
    if (eventData.uploadId === uploadId) {
      setValue(`courseLectures.${index}.lectureVideo`, eventData.id);
      // 移除监听器,避免内存泄漏
      socket.off("upload-progress", handleProgress);
      socket.off("upload-success", handleSuccess);
    }
  };

  // 绑定监听器
  socket.on("upload-progress", handleProgress);
  socket.on("upload-success", handleSuccess);
}

2. 后端代码修改

接收前端传来的uploadId,在发送进度、成功、失败事件时携带该标识,让前端能精准匹配任务:

async handleFileUpload(@MessageBody() data: any, @ConnectedSocket() client: Socket) {
  const file = data.file;
  const meta = data.fileMeta;
  const name = data.name;
  const uploadId = data.uploadId; // 获取前端传入的唯一标识
  const filename = this.getCompleteFileName(meta);
  const completePath = join('video-lectures', filename);

  await promises.writeFile(completePath, file);

  this.vimeoClient.upload(
    completePath,
    { name },
    async (uri: string) => {
      const video = new Video();
      video.url = uri;
      const result = await this.videoRepository.save(video);
      // 返回uploadId与视频ID
      client.emit('upload-success', { uploadId, id: result.id });
    },
    (bytesUploaded: number, bytesTotal: number) => {
      const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
      // 返回uploadId与进度百分比
      client.emit('upload-progress', { uploadId, percentage });
    },
    error => {
      console.log('Failed because: ' + error);
      // 失败事件同样携带uploadId
      client.emit('upload-failed', { uploadId, error });
    },
  );
}

额外优化

  • 建议添加upload-failed事件的监听逻辑,同样通过uploadId匹配任务,并在失败时移除对应监听器
  • 组件卸载时,调用socket.off()移除所有相关监听器,彻底避免内存泄漏

内容的提问来源于stack exchange,提问作者Abdul Ahad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 20:32:43