“文件传得慢”看起来像一个问题,实际可能发生在完全不同的层:无线网络本身慢、连接绕到远处的 TURN、浏览器缓冲区被塞满、接收端写盘跟不上,或者应用每发一小块都等待一次确认。只测一次速度然后更换服务器,很容易把偶发症状当根因。
最有价值的线索往往是对照:同一对设备直连快、中继慢;屏幕共享经中继能到几百 KB/s,文件却只有十几 KB/s;一个大文件正常,上万个小文件很慢。这些差异能把排查范围迅速缩小。
先记一组能比较的基线
准备一个 200 MB 左右、内容不敏感的测试文件,在相同设备上分别记录连接路径、稳定后的平均速度、延迟、浏览器版本和网络类型。不要用头两秒的峰值,也不要同时下载更新或开视频会议。若条件允许,再换一条网络复测,例如电脑连家庭宽带、手机连 5G。
界面应区分三个进度:写入发送缓冲、远端确认接收、最终摘要校验。只有远端确认字节适合计算有效吞吐。若进度条冲到 100% 后等待很久,问题可能是本地排队过深或接收端校验慢,而不是线路突然停止。
确认走的是哪条路
同一局域网应优先出现主机候选之间的直连。若显示 TURN,中间可能有访客 Wi-Fi 隔离、VPN、系统防火墙或浏览器网络策略。跨网络中继则可能是正常结果,此时要看中继机房是否靠近双方、是否拥塞,以及协议能否利用较长的往返时间。
可以用一个简单判断:如果音视频、屏幕共享和文件都按相近比例变慢,网络或中继容量更可疑;如果只有文件通道异常,而屏幕共享稳定,应用层传输算法的优先级更高。
检查 bufferedAmount 和背压
RTCDataChannel.send() 返回不代表数据已经到达对方,只表示浏览器接受了这次排队。不断发送会让 bufferedAmount 上升。缓冲过大不仅吃内存,还会让取消、进度确认和心跳等控制消息排在大文件后面。
发送器应设置高低水位:达到上限就暂停,在 bufferedamountlow 事件或确认窗口腾出后继续。上限不能只写死为一个极大值,应该结合设备内存、分块大小和当前往返时间。移动浏览器尤其不适合积压数百 MB。
分块和确认窗口要一起调
块太小,每个块的消息、索引和确认开销会占掉大量时间;块太大,单次排队和重传成本又会上升。常见起点是几十 KB 级分块,再让多个块在途,而不是“一发一等”。真正需要调的是在途字节窗口,而不只是块大小。
中继链路往返时间较长时,停等协议尤其吃亏。假设每发 64 KB 都等待 100 毫秒确认,理论上也只有约 640 KB/s;如果还叠加定时器和主线程忙碌,速度会更低。使用累积确认或区间确认,让窗口里保持足够数据,才能填满链路。
别让重传和其他功能互相堵塞
聊天、取消、文件控制和数据块可以使用独立通道,或至少进入有优先级的调度器。控制消息应先于普通文件块。多个文件并发时采用轮转或加权公平队列,避免第一个大文件把其他任务锁死。
丢块后也不必回退到最后一个连续位置重发全部数据。接收方维护已到达区间,定期报告缺口;发送方选择性补发。若缺口反复集中在同一区间,检查块编号、二进制序列化和落盘事务,而不应无限加大超时。
接收端也可能是瓶颈
低端手机同时接收、计算 SHA-256、写入 IndexedDB 并刷新界面,主线程很容易繁忙。可把摘要计算放到 Worker,批量提交存储事务,降低进度 UI 的刷新频率。磁盘空间不足或浏览器存储配额临界时,应提前失败并给出原因,不能表现成网络越来越慢。
测试时观察页面是否掉帧、设备是否发热、切到后台后速度是否骤降。移动系统会限制后台标签页,这是平台行为。大文件传输页应提醒用户保持前台,并在恢复可见时重新核对任务状态。
一个不绕弯的排查顺序
- 确认有效速度口径和当前直连或中继路径。
- 同设备换网络、同网络换设备,判断问题跟着哪一侧走。
- 比较屏幕共享或其他 WebRTC 流量,区分线路与文件协议。
- 记录
bufferedAmount、在途窗口、确认间隔和重传比例。 - 观察接收端写盘、摘要、主线程和存储配额。
- 最后再调整块大小、窗口和中继部署,每次只改一个变量。
普通用户能先做什么
在 uCopy 工作区确认路径后,先关闭 VPN,避免使用访客 Wi-Fi,把浏览器保持在前台,并用一个较大的单文件复测。若直连正常而中继持续异常,记录大致地域与稳定速度;若屏幕共享正常而文件慢,把这个对照写进反馈,它比一张 0% 的截图更能指向算法。
速度问题最怕“凭感觉优化”。有路径、有对照、有分层指标,才能分清是带宽确实有限,还是代码没有把已有带宽用起来。