React-Native-WebRTC如何正确结束通话 解决退出房间后音频残留问题
问题根因与修复方案
核心问题
你在createPC方法中重写了RTCPeerConnection的原生close方法,仅保留了日志打印逻辑,完全覆盖了原生关闭连接、释放音视频资源的底层实现,这是退出后远端音频依然播放的最主要原因。
其他需修复的缺陷
leave方法中直接操作this.state.remoteList执行删除,没有通过setState更新状态,会导致旧的远端流引用残留内存无法释放closeRtc方法中对forEach返回值使用await,forEach本身返回undefined,await不会等待所有轨道、连接关闭完成就会执行后续跳页逻辑,导致资源清理没完成就跳转- 仅在
closeRtc中解绑socket事件,没有在组件卸载生命周期补充清理逻辑,若组件被意外卸载会导致重复创建连接、事件重复触发
修复步骤
- 恢复RTCPeerConnection的close原生逻辑,修改
createPC中自定义的close方法:
// 保存原有的close方法 const originClose = peer.close.bind(peer); peer.close = () => { console.log("peer close"); // 调用原生关闭逻辑 originClose(); }
也可以直接删除你自定义的peer.close重写代码,完全使用原生实现。
2. 修改leave方法的状态更新逻辑:
leave = (idLeave) => { if (idLeave in this.pcPeers) { const tracks = this.state.remoteList[idLeave].getTracks(); const pc = this.pcPeers[idLeave]; tracks.forEach(track => track.stop()); pc?.close(); delete this.pcPeers[idLeave]; // 不要直接修改state,通过setState更新 const newRemoteList = {...this.state.remoteList}; delete newRemoteList[idLeave]; this.setState({remoteList: newRemoteList}); } };
- 修改
closeRtc的异步清理逻辑,去掉无效的await:
closeRtc = async() => { if (this.state.localStream) { this.stopTracks(this.state.localStream); // 加兼容判断,避免低版本SDK无release方法报错 this.state.localStream.release?.(); } // 逐个关闭远端轨道 for (const [_, stream] of Object.entries(this.state.remoteList)) { stream.getTracks().forEach(track => track.stop()); } // 逐个关闭peer连接 for (const [_, pc] of Object.entries(this.pcPeers)) { pc.close(); } // 后续原有逻辑保持不变 this.setState({ remoteList: {}, localStream: '', }); this.pcPeers = {}; ... }
- 新增
componentWillUnmount生命周期,补充兜底清理逻辑:
componentWillUnmount() { // 若组件卸载前还未清理资源,执行清理 if (Object.keys(this.pcPeers).length > 0 || this.state.localStream) { this.closeRtc(); } }
内容的提问来源于stack exchange,提问作者Florian
相关产品推荐
相关产品推荐

