Flutter WebRTC网络问题:移动数据可通话,WiFi下连接停滞在Checking
解决Flutter WebRTC P2P视频通话WiFi网络无法连接的问题
这问题我之前帮朋友排查过类似的,大概率是WiFi网络的限制、STUN/TURN配置或者WebRTC的ICE候选流程出了问题,咱们一步步来拆解排查:
1. 先排查WiFi网络的NAT类型与端口限制
很多家庭或企业WiFi用的是对称NAT,这种NAT下STUN服务器很难穿透,而移动数据网络通常是锥型NAT,更容易建立P2P连接。你可以这么验证:
- 在Flutter里打印ICE候选的收集日志,看WiFi环境下是否能拿到有效的公网候选(服务器反射候选或中继候选),如果只有本地主机候选,那说明STUN/TURN没起作用。
- 有些WiFi会限制UDP端口(WebRTC默认优先用UDP传输),可以尝试强制WebRTC使用TCP传输,在
RTCConfiguration里添加配置:
或者直接强制走TURN中继(虽然会增加延迟,但能验证是否是NAT问题):final config = { 'iceServers': [/* 你的STUN/TURN配置 */], 'iceTransportPolicy': 'all', 'sdpSemantics': 'unifiedPlan' };'iceTransportPolicy': 'relay'
2. 检查Google STUN/TURN服务器的配置是否正确
Google的公开STUN服务器(stun:stun.l.google.com:19302)一般没问题,但TURN服务器需要正确的认证信息,你是不是只配置了STUN没配TURN?正确的Google TURN配置应该是这样的:
final config = { 'iceServers': [ { 'urls': 'stun:stun.l.google.com:19302' }, { 'urls': 'turn:turn.l.google.com:19305', 'username': 'your-username', // 可以用当前时间戳生成 'credential': 'your-credential' // 对应用户名的密钥,可通过TURN服务器的算法生成 } ] };
如果WiFi下无法获取TURN中继候选,大概率是网络屏蔽了TURN服务器的端口,或者认证信息不对。
3. 验证Socket.io信令的网络兼容性
有些WiFi网络会限制WebSocket连接(socket.io默认优先用WebSocket),可以尝试强制socket.io使用HTTP长轮询模式,绕过WebSocket限制:
IO.Socket socket = IO.io('你的信令服务器地址', OptionBuilder() .setTransports(['polling']) // 强制使用长轮询 .build() );
同时确认信令服务器在WiFi环境下能正常访问,比如用浏览器打开信令服务器的测试接口,看是否能返回响应。
4. 检查WebRTC的ICE候选流程是否正确
确保你正确处理了ICE候选的发送与接收:
- 监听
onIceCandidate事件,把生成的候选通过信令服务器发送给对方:peerConnection.onIceCandidate = (RTCIceCandidate candidate) { if (candidate != null) { socket.emit('ice-candidate', candidate.toMap()); } }; - 接收对方的候选后,要正确添加到本地
RTCPeerConnection:socket.on('ice-candidate', (data) async { await peerConnection.addCandidate(RTCIceCandidate.fromMap(data)); });
另外,监听onConnectionStateChange和onIceConnectionStateChange事件,打印详细日志,看WiFi下停在checking阶段时有没有错误信息输出。
5. 确认设备的网络权限配置
- Android端:在
AndroidManifest.xml里确保添加了必要的权限:<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> - iOS端:在
Info.plist里配置网络权限相关项,比如允许HTTP请求(如果信令服务器是HTTP的话):<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
先从WiFi的NAT类型和STUN/TURN配置入手排查,这两个是此类问题最常见的根源,逐步验证应该能定位到问题所在。
内容的提问来源于stack exchange,提问作者Suraj Aggarwal




