You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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里添加配置:
    final config = {
      'iceServers': [/* 你的STUN/TURN配置 */],
      'iceTransportPolicy': 'all',
      'sdpSemantics': 'unifiedPlan'
    };
    
    或者直接强制走TURN中继(虽然会增加延迟,但能验证是否是NAT问题):
    '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));
    });
    

另外,监听onConnectionStateChangeonIceConnectionStateChange事件,打印详细日志,看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

火山引擎 最新活动