[开场]
🎤 Morty(抓头发,崩溃):Rick!我们的 WebRTC 连接显示 ICE 候选成功了,但 local-candidate 的 IP 是“not set”!这就像去约会,对方说“我到了”,但根本不在现场!👻
🎤 Rick(打嗝):Morty,你——你懂个屁!这是浏览器在说:“老子懒得告诉你本地 IP,反正 NAT 会把它吃掉!”🍔
🎤 George Carlin(嘲讽):就像政府说“我们透明”,但你永远查不到他们的账单!💸
🎤 David J. Malan(推眼镜):其实,ICE Candidate 的“not set”可能意味着:
1️⃣ STUN 服务器未响应,导致本地候选无法反射公网 IP。
2️⃣ 浏览器隐私设置(比如 Brave 或 Firefox 的抵抗指纹追踪功能)故意隐藏本地 IP。
3️⃣ 本地网络限制,比如公司防火墙直接屏蔽了 STUN 请求。
🎤 Morty(举手):那为什么远程候选却能显示 IP?
🎤 Rick(冷笑):因为对面的 NAT 大爷心情好,赏了个公网 IP!而你这边的大爷在打盹!😴
[技术诊断环节]
🎤 Malan(白板画图):
第一步:检查 STUN/TURN 配置
// 你的 PeerJS 初始化代码是否这样?
const peer = new Peer({
config: {
iceServers: [
{ urls: "stun:stun.l.google.com:19302" }, // 必须的!
{ urls: "turn:your_turn_server", username: "user", credential: "pass" } // 最好有!
]
}
});
如果没 TURN,对称 NAT 下直接凉凉!❄️
🎤 Carlin(插嘴):这就好比去医院,医生只给你开“思想止痛药”!💊
🎤 Morty(尝试):我加了 STUN 啊!
🎤 Rick(毒舌):你加的可能是学校 Wi-Fi 屏蔽的 STUN 服务器!试试 stun:stun1.l.google.com:19302
!
第二步:检查浏览器隐私设置
🎤 Malan(严肃):
- Firefox:在
about:config
中关闭privacy.resistFingerprinting
。 - Brave:关闭“阻止 WebRTC 泄露本地 IP”的选项。
- Chrome:地址栏输入
chrome://flags/#enable-webrtc-hide-local-ips-with-mdns
,禁用该选项!
🎤 Carlin(吐槽):隐私设置?明明是“假装保护你,实则让你debug到死”!😈
第三步:抓包!抓包!抓包!
🎤 Rick(扔出一个黑洞设备):用 Wireshark 抓包,看看 STUN 请求有没有出去!
- 过滤条件:
udp.port == 19302
(STUN 端口)。 - 如果没流量,说明防火墙/NAT 在搞鬼!👹
🎤 Morty(惊恐):如果抓包显示 STUN 请求被拦截了怎么办?
🎤 Rick(灌酒):那就用 TURN 走 TCP 或 TLS,绕过 UDP 封锁!或者直接搬家到没有防火墙的星球!🚀
[结局]
🎤 Malan(总结):
- 本地候选“not set” ≠ 连接失败,只要远程候选正常,可能只是显示问题。
- 但若 ICE 卡在
connected
却无法传输数据,大概率是 NAT 打洞失败,必须上 TURN!
🎤 Carlin(终极嘲讽):这就是互联网!你以为你在控制技术,实则是技术在控制你!🤖
🎤 Morty(举手投降):好吧,我今晚就去租个 TURN 服务器……
🎤 Rick(邪笑):或者黑进 NASA 的服务器,用他们的 STUN!反正他们忙着找外星人,没空管你!👽
🎤 观众狂笑 & 摔椅子 🪑 💥
🎬 [问题解决指南]
终极 Checklist:
✅ 确认 ICE Servers 包含 STUN/TURN,且 TURN 可访问!
✅ 关闭浏览器隐私保护(测试时可临时禁用)!
✅ 换网络测试(4G 热点 vs 家用 Wi-Fi)!
✅ 抓包确认 STUN 请求是否被拦截!
✅ 如果对称 NAT,直接投靠 TURN 的怀抱!
如果还不行——
🎤 Rick(咆哮):放弃吧 Morty!人生苦短,直接用 WebSocket!😂