调试与日志:浏览器调试工具、webrtc-internals、日志收集、常见错误排查

调试WebRTC应用,说实话,有时候比写代码还让人头疼。为什么?因为实时通信涉及网络、编码、信令、ICE协商等多个环节,任何一个地方出问题,视频就可能黑屏、卡顿,或者干脆连不上。

我个人习惯,在写WebRTC代码之前,先把调试工具链搭好。这样出了问题,能快速定位。今天我们就聊聊怎么用好浏览器自带的调试工具,以及如何收集日志、排查常见错误。

浏览器调试工具:不只是看控制台

Chrome DevTools 大家都会用,但WebRTC调试有几个特殊面板,很多人忽略了。

Network面板:看信令交互

信令交换是WebRTC的第一步。打开Network面板,过滤出WebSocket或HTTP请求,你能看到SDP的offer/answer是怎么传递的。我遇到过好几次,问题就出在信令服务器没把SDP正确转发——在Network里一看,哦,JSON字段名拼错了。

小技巧: 在Network面板里右键点击请求,选择"Copy as cURL",可以直接在终端里重放请求,方便测试信令服务器。

Console面板:捕获异常

WebRTC的API很多是异步的,错误往往藏在Promise的catch里。我建议你在代码里统一加一个全局的异常捕获:

window.addEventListener('unhandledrejection', event => {
  console.error('未捕获的Promise错误:', event.reason);
});

嗯,这个习惯帮我省了不少排查时间。

webrtc-internals:WebRTC的“黑匣子”

这是Chrome内置的调试神器。在地址栏输入 chrome://webrtc-internals,你会看到一个实时更新的仪表盘。这里能看到所有PeerConnection的详细信息。

核心指标解读

指标 含义 正常范围
googRtt 往返时延 < 200ms
googFrameRateReceived 接收帧率 ≥ 24fps
googFrameWidth/Height 视频分辨率 取决于编码设置
googPacketsLost 丢包数 占总包数 < 5%
googJitterBufferMs 抖动缓冲 20-100ms

我曾经帮一个客户排查视频卡顿问题,打开webrtc-internals一看,googRtt飙到了800ms。后来发现是用户连了VPN,路由绕了半个地球。说白了,网络问题在数据面前一目了然。

导出日志

在webrtc-internals页面,点击"Export"按钮,可以导出完整的日志文件。这个文件是JSON格式的,包含了所有统计数据和事件。我建议你在每次测试结束后都导出一份,方便对比分析。

注意: 导出日志会包含ICE候选地址等网络信息。如果涉及用户隐私,记得脱敏处理。

日志收集:从客户端到服务端

光靠浏览器自带的工具还不够。生产环境里,我们需要把日志收集到服务端,才能做全局分析。

客户端日志分级

我习惯在代码里实现一个简单的日志系统:

const LOG_LEVELS = {
  DEBUG: 0,
  INFO: 1,
  WARN: 2,
  ERROR: 3
};

class WebRTCLogger {
  constructor(level = LOG_LEVELS.INFO) {
    this.level = level;
    this.buffer = [];
  }

  log(level, tag, message, data = null) {
    if (level < this.level) return;
    const entry = {
      timestamp: Date.now(),
      level: Object.keys(LOG_LEVELS)[level],
      tag,
      message,
      data
    };
    this.buffer.push(entry);
    // 同时输出到控制台
    console.log(`[${entry.level}][${tag}] ${message}`, data);
  }

  flush() {
    // 将buffer发送到服务端
    navigator.sendBeacon('/api/logs', JSON.stringify(this.buffer));
    this.buffer = [];
  }
}

const logger = new WebRTCLogger(LOG_LEVELS.DEBUG);

你看,这里用了 sendBeacon 而不是普通的fetch。为什么?因为页面关闭时,fetch请求可能被中断,而sendBeacon能保证数据送达。这个坑我踩过,现在长记性了。

关键日志点

在WebRTC的生命周期里,有几个地方一定要打日志:

  • 创建PeerConnection时:记录ICE服务器配置
  • 收到SDP时:记录SDP的type和媒体信息
  • ICE状态变化时:记录每个状态的切换时间
  • 数据通道打开/关闭时:记录通道标签和ID
  • 发生错误时:记录完整的错误堆栈
核心原则: 日志要能复现问题现场。光说"视频卡了"没用,得有RTT、丢包率、帧率这些数据。

常见错误排查

做WebRTC开发,有些错误你迟早会遇到。我整理了几个高频问题,以及排查思路。

ICE连接失败

症状:PeerConnection的iceConnectionState一直卡在checking,或者变成failed。

排查步骤:

  1. 检查ICE服务器配置是否正确。STUN/TURN的URL和凭证对不对?
  2. 在webrtc-internals里看ICE候选是否生成。如果本地候选为空,可能是网卡问题。
  3. 检查防火墙是否阻断了UDP端口。TURN服务器通常用3478端口。
  4. 如果用了TURN,确认TURN服务器是否正常运行。

我记得有一次,用户反馈连不上,查了半天发现是STUN服务器域名解析错了。说白了,基础网络配置最容易出问题。

媒体流没有画面

症状:连接建立成功,但remote video元素是黑的。

排查思路:

  • 检查getUserMedia是否成功获取了本地流。可以在控制台打印stream.getTracks()。
  • 确认addTrack是否调用了。很多新手忘了把track添加到PeerConnection。
  • 在webrtc-internals里看"Video Received"字段。如果为0,说明远端没收到视频包。
  • 检查SDP里是否有视频媒体段。有时候信令服务器把视频m-line过滤掉了。

音频回声或噪音

症状:通话中有回声,或者背景噪音很大。

解决方案:

  • 启用回声消除:audio: { echoCancellation: true }
  • 启用降噪:audio: { noiseSuppression: true }
  • 检查音频设备。有些廉价麦克风硬件上就有回声。
避坑指南: 我曾经在Chrome上遇到过,某些版本的echoCancellation在Windows上失效。后来发现是音频驱动的问题,更新驱动就好了。遇到这种问题,先换个浏览器试试。

知识体系总览

下面这张图,把调试与日志的核心流程串起来了。你可以把它当作排查问题的路线图。

WebRTC调试与日志排查流程 问题发现 选择调试工具 Chrome DevTools Network / Console webrtc-internals 统计 / 日志导出 自定义日志系统 分级 / 上报 分析数据 → 定位根因

这张图展示了从发现问题到定位根因的完整链路。你想想看,如果没有这些工具,出了问题只能靠猜,那得多痛苦。

调试WebRTC,说白了就是和数据打交道。浏览器给了我们webrtc-internals这样的利器,我们自己再搭一套日志系统,大部分问题都能在几分钟内定位。剩下的那些疑难杂症,往往需要结合网络抓包(比如Wireshark)来分析,那就是另一个话题了。

嗯,今天就聊到这里。记住,调试不是事后补救,而是开发流程的一部分。把日志打好了,把工具用熟了,你的WebRTC开发效率至少提升一倍。


公众号:蓝海资料掘金营,微信deep3321