调试与日志:浏览器调试工具、webrtc-internals、日志收集、常见错误排查
调试WebRTC应用,说实话,有时候比写代码还让人头疼。为什么?因为实时通信涉及网络、编码、信令、ICE协商等多个环节,任何一个地方出问题,视频就可能黑屏、卡顿,或者干脆连不上。
我个人习惯,在写WebRTC代码之前,先把调试工具链搭好。这样出了问题,能快速定位。今天我们就聊聊怎么用好浏览器自带的调试工具,以及如何收集日志、排查常见错误。
浏览器调试工具:不只是看控制台
Chrome DevTools 大家都会用,但WebRTC调试有几个特殊面板,很多人忽略了。
Network面板:看信令交互
信令交换是WebRTC的第一步。打开Network面板,过滤出WebSocket或HTTP请求,你能看到SDP的offer/answer是怎么传递的。我遇到过好几次,问题就出在信令服务器没把SDP正确转发——在Network里一看,哦,JSON字段名拼错了。
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格式的,包含了所有统计数据和事件。我建议你在每次测试结束后都导出一份,方便对比分析。
日志收集:从客户端到服务端
光靠浏览器自带的工具还不够。生产环境里,我们需要把日志收集到服务端,才能做全局分析。
客户端日志分级
我习惯在代码里实现一个简单的日志系统:
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
- 发生错误时:记录完整的错误堆栈
常见错误排查
做WebRTC开发,有些错误你迟早会遇到。我整理了几个高频问题,以及排查思路。
ICE连接失败
症状:PeerConnection的iceConnectionState一直卡在checking,或者变成failed。
排查步骤:
- 检查ICE服务器配置是否正确。STUN/TURN的URL和凭证对不对?
- 在webrtc-internals里看ICE候选是否生成。如果本地候选为空,可能是网卡问题。
- 检查防火墙是否阻断了UDP端口。TURN服务器通常用3478端口。
- 如果用了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 } - 检查音频设备。有些廉价麦克风硬件上就有回声。
知识体系总览
下面这张图,把调试与日志的核心流程串起来了。你可以把它当作排查问题的路线图。
这张图展示了从发现问题到定位根因的完整链路。你想想看,如果没有这些工具,出了问题只能靠猜,那得多痛苦。
调试WebRTC,说白了就是和数据打交道。浏览器给了我们webrtc-internals这样的利器,我们自己再搭一套日志系统,大部分问题都能在几分钟内定位。剩下的那些疑难杂症,往往需要结合网络抓包(比如Wireshark)来分析,那就是另一个话题了。
嗯,今天就聊到这里。记住,调试不是事后补救,而是开发流程的一部分。把日志打好了,把工具用熟了,你的WebRTC开发效率至少提升一倍。