You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

浏览器与Django服务器间RTCPeerConnection连接失败求助

问题分析与解决建议

问题现象

  • 服务器可接收浏览器Offer,浏览器能接收服务器Answer,但在部分WiFi、4G移动网络下连接中断,本地及部分WiFi环境连接正常
  • 浏览器控制台打印“receive server video”及MediaStream对象,但视频元素无画面显示
  • 服务器日志显示连接状态从connecting变为failed,最终转为closed
  • 出现InvalidStateError('invalid state')错误,溯源至aioice库的TurnClientMixin逻辑

服务器端代码

@aioConnection.on("connectionstatechange")
async def on_connectionstatechange():
    print("Connection state is %s" % aioConnection.connectionState)

@aioConnection.on("track")
def on_track(track):
    print("======= received track: ", track, flush=True)
            if track.kind == "video":
        newTrack = VideoStreamTrack(track)
        aioConnection.addTrack(newTrack)

服务器日志

Oct  5 06:00:43 ip-172-31-30-121 gunicorn[2999]: /home/ubuntu/.local/lib/python3.10/site-packages/aiortc/rtcdtlstransport.py:186: CryptographyDeprecationWarning: This version of cryptography contains a temporary pyOpenSSL fallback path. Upgrade pyOpenSSL now.
Oct  5 06:00:43 ip-172-31-30-121 gunicorn[2999]:   value=certificate_digest(self._cert._x509),  # type: ignore
Oct  5 06:00:43 ip-172-31-30-121 gunicorn[2999]: ======= received track:  <aiortc.rtcrtpreceiver.RemoteStreamTrack object at 0x7efde9842ec0>
Oct  5 06:00:43 ip-172-31-30-121 gunicorn[2999]: Connection 1 state is connecting
Oct  5 06:01:15 ip-172-31-30-121 gunicorn[2999]: Connection 1 state is failed
Oct  5 06:01:15 ip-172-31-30-121 gunicorn[2999]: Connection 1 state is closed

浏览器端代码

aioConnection.addEventListener('track', function (evt) {
    console.log("receive server video");
    console.log(evt.streams[0])
    document.getElementById("video").srcObject = evt.streams[0];
});

关键错误日志

Task exception was never retrieved
<Task finished name='Task-82' coro=<TurnClientMixin.delete() done, defined at /home/ubuntu/.local/lib/python3.10/site-packages/aioice/turn.py:147> exception=InvalidStateError('invalid state')>
Traceback (most recent call last):
File "/home/ubuntu/.local/lib/python3.10/site-packages/aioice/turn.py", line 167, in delete
self.receiver.connection_lost(None)
File "/home/ubuntu/.local/lib/python3.10/site-packages/aioice/ice.py", line 175, in connection_lost
self.__closed.set_result(True)
asyncio.exceptions.InvalidStateError: invalid state

解决建议

1. 补全STUN/TURN服务器配置

部分网络(如4G、严格NAT的WiFi)无法直接建立P2P连接,必须依赖中转服务器:

  • 服务器端和浏览器端均需配置有效的STUN/TURN服务器地址、用户名及密码
  • 用trickle-ice工具验证网络能否通过STUN获取公网地址,或通过TURN中转流量
  • 强制开启TURN中转,避免依赖不稳定的P2P连接

2. 修复ICE连接异常处理

日志中的InvalidStateError是ICE连接失败后,aioice内部重复标记连接关闭导致的,需从根源解决ICE问题:

  • 调整ICE连接超时阈值,避免过早判定连接失败
  • 服务器端新增iceconnectionstatechange事件监听,排查ICE候选是否正常交换
  • 确保浏览器端收集并发送所有ICE候选到服务器,服务器端同步推送自身ICE候选给浏览器

3. 修正视频轨道与播放逻辑

浏览器收到MediaStream但无画面,多因轨道未激活或视频元素属性缺失:

  • 给视频元素添加必要属性,适配移动端播放:
    <video id="video" autoplay playsinline muted></video>
    
  • 修复服务器端on_track函数的缩进错误,确保视频轨道正确初始化并添加:
    @aioConnection.on("track")
    def on_track(track):
        print("======= received track: ", track, flush=True)
        if track.kind == "video":
            newTrack = VideoStreamTrack(track)
            aioConnection.addTrack(newTrack)
    

4. 升级依赖库解决DTLS警告

服务器日志中的加密库警告可能引发DTLS握手问题,执行以下命令更新依赖:

pip install --upgrade pyopenssl cryptography

5. 排查网络端口与防火墙限制

  • 检查服务器防火墙是否开放ICE/RTCP所需端口(UDP 3478、443及动态端口范围)
  • 4G网络下需确认运营商未限制RTMP/RTCP流量,必要时切换TURN服务器端口为443

内容的提问来源于stack exchange,提问作者Ikochoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 12:30:55