20、WebRTC调试工具:chrome://webrtc-internals、Wireshark抓包分析、日志系统
做WebRTC开发,最头疼的是什么?
不是写代码,是出了问题不知道去哪查。信令通了,媒体流就是出不来;视频卡成PPT,但网络明明很好。这种问题,我遇到过太多次了。
今天我就把压箱底的调试三板斧教给你。这三样东西用熟了,WebRTC的问题基本都能定位。
20.1 chrome://webrtc-internals:浏览器自带的诊断神器
先说说我最常用的工具。Chrome浏览器里输入 chrome://webrtc-internals,回车,一个实时诊断面板就出来了。
这个页面记录了所有WebRTC连接的内部状态。说白了,就是浏览器把底层的ICE、SDP、统计信息全给你摊开了。
20.1.1 核心面板解读
打开之后,你会看到几个关键区域:
| 面板名称 | 作用 | 我常看什么 |
|---|---|---|
| Stats Table | 实时统计信息 | 丢包率、RTT、码率 |
| ICE Connection State | ICE连接状态 | 是不是卡在checking了 |
| SDP Offer/Answer | 媒体协商内容 | 编解码器有没有匹配上 |
| Candidate Pair | 候选地址对 | 是不是走了relay |
重点盯住这几个指标:
googRtt:往返时延,超过300ms就要警惕packetsLost:丢包数,持续增长说明网络不行bytesSent/bytesReceived:实际传输量,跟码率设置对比
20.1.2 实战:抓取一次通话的全量日志
我建议你养成一个习惯:每次测试前,先打开 chrome://webrtc-internals,然后点「Create Dump」按钮。
通话结束后,再点「Save Dump」,就能导出一个JSON文件。这个文件包含了整个通话过程中所有的统计快照。
我的小技巧:
把dump文件保存下来,跟bug报告一起提交。这样后端同事也能复现你的环境。我曾经靠这个帮团队定位过一个只在特定NAT下才出现的ICE失败问题。
20.2 Wireshark抓包分析:网络层的火眼金睛
浏览器工具能看到应用层,但网络层的问题还得靠Wireshark。比如:
- STUN请求有没有被中间设备拦截?
- DTLS握手是不是超时了?
- RTP包的序列号有没有乱序?
20.2.1 过滤规则速查
Wireshark抓包数据量很大,不设过滤等于大海捞针。我常用的过滤规则:
# 只看WebRTC相关流量
stun || dtls || rtp || rtcp
# 只看某个IP的RTP流
ip.addr == 192.168.1.100 && rtp
# 只看ICE的STUN消息
stun && !icmp
# 过滤出某个SSRC的流
rtp.ssrc == 0x12345678
注意:抓包时记得关闭其他浏览器标签页,否则流量会混在一起。我一般用Chrome的无痕模式,只开一个页面。
20.2.2 分析RTP流质量
Wireshark内置了RTP分析功能。选中一个RTP包,右键→「Telephony」→「RTP」→「Stream Analysis」。
你会看到:
- 丢包率:Delta > 20ms就算丢包
- 抖动:超过50ms就会感觉卡顿
- 序列号:有没有跳号或重复
嗯,这里要注意:Wireshark显示的丢包率是网络层的,跟浏览器统计的可能不一样。因为浏览器统计的是应用层丢包,包含了jitter buffer丢弃的包。
20.3 日志系统:自己动手丰衣足食
浏览器工具和Wireshark都是事后分析。但有些问题,比如信令交互的时序、自定义协议的解析,还得靠自己的日志系统。
20.3.1 日志分级策略
我习惯把日志分成四级:
| 级别 | 标签 | 使用场景 |
|---|---|---|
| ERROR | [E] | 连接失败、ICE超时、DTLS错误 |
| WARN | [W] | 丢包率过高、码率波动大、候选地址切换 |
| INFO | [I] | 连接建立、ICE状态变化、SDP交换完成 |
| DEBUG | [D] | STUN请求/响应详情、RTP包序列号 |
20.3.2 一个实用的日志工具类
这是我项目里一直在用的日志工具,简单但够用:
class WebrtcLogger {
constructor(peerId) {
this.peerId = peerId;
this.logs = [];
}
log(level, tag, message, data = null) {
const entry = {
timestamp: new Date().toISOString(),
peerId: this.peerId,
level,
tag,
message,
data
};
this.logs.push(entry);
// 控制台输出带颜色
const prefix = `[${entry.timestamp}] [${level}] [${tag}]`;
if (level === 'ERROR') console.error(prefix, message, data);
else if (level === 'WARN') console.warn(prefix, message, data);
else console.log(prefix, message, data);
}
// 专门记录ICE事件
onIceCandidate(candidate) {
this.log('D', 'ICE', '新候选地址', {
type: candidate.type,
protocol: candidate.protocol,
address: candidate.address,
port: candidate.port
});
}
// 记录连接状态变化
onConnectionState(state) {
this.log('I', 'CONN', `连接状态变为: ${state}`);
if (state === 'failed') {
this.log('E', 'CONN', '连接失败,触发重连');
}
}
// 导出日志用于分析
export() {
return JSON.stringify(this.logs, null, 2);
}
}
我的经验:日志里一定要带上时间戳和peerId。多端通话时,没有这两个字段,你根本对不上谁先谁后。
20.4 三件套配合使用
你想想看,这三个工具其实是互补的:
- chrome://webrtc-internals:看应用层状态,适合快速定位
- Wireshark:看网络层细节,适合深挖根因
- 日志系统:看业务逻辑,适合排查自定义问题
我遇到复杂问题时,会同时打开这三个。先看浏览器面板有没有异常指标,然后去Wireshark里验证网络层,最后翻日志确认业务逻辑是否正确。
避坑指南:
我曾经遇到一个诡异的问题:视频偶尔黑屏,但音频正常。浏览器面板显示码率正常,Wireshark也看不出问题。最后翻日志发现,是某个信令消息里把video direction设成了"recvonly",导致远端没发视频流。这种问题,光靠网络工具是查不出来的。
20.5 知识体系总览
下面这张图概括了本章的核心内容,你可以把它当作调试时的路线图:
这三个工具用熟了,WebRTC调试对你来说就不再是黑盒。下次遇到问题,别急着改代码,先打开这三个工具看看数据怎么说。
公众号:蓝海资料掘金营,微信deep3321