WebRTC项目故障:关闭自身视频通话致所有连接断开,求代码修复
问题原因与解决方案
你的代码核心问题是用了单个myPeerConnection变量存储连接,在多客户端房间场景里,每个其他客户端都需要对应独立的RTCPeerConnection实例,而不是共用一个。所以挂断时会把唯一的连接关掉,导致所有通话断开。下面是具体修改方案:
核心修改思路
- 用连接映射表替代单个连接变量,每个用户对应独立的连接实例
- 让挂断逻辑只针对指定用户的连接,而非全部关闭
- 只有当所有连接都断开时,才停止本地摄像头(避免影响其他活跃通话)
修改后的代码示例
// 替换单个myPeerConnection为连接映射表,键是对方用户名,值是对应RTCPeerConnection实例 let peerConnections = {}; // 跟踪活跃连接数量,用来判断是否需要停止本地摄像头 let activeConnectionsCount = 0; /* 关闭与指定用户的视频通话,而非全部 */ function closeVideoCall(targetUsername) { const localVideo = document.getElementById("local_video"); log(`Closing call with ${targetUsername}`); // 获取对应目标的连接实例,不存在则直接返回 const peerConnection = peerConnections[targetUsername]; if (!peerConnection) return; log(`--> Closing peer connection with ${targetUsername}`); // 移除该连接的所有事件监听 peerConnection.ontrack = null; peerConnection.onnicecandidate = null; peerConnection.oniceconnectionstatechange = null; peerConnection.onsignalingstatechange = null; peerConnection.onicegatheringstatechange = null; peerConnection.onnotificationneeded = null; // 停止该连接的所有收发器 peerConnection.getTransceivers().forEach(transceiver => { transceiver.stop(); }); // 关闭连接并从映射表中移除 peerConnection.close(); delete peerConnections[targetUsername]; activeConnectionsCount--; // 只有当所有连接都关闭时,才停止本地摄像头预览 if (activeConnectionsCount === 0) { if (localVideo.srcObject) { localVideo.pause(); localVideo.srcObject.getTracks().forEach(track => { track.stop(); }); webcamStream = null; } // 没有活跃连接时禁用挂断按钮 document.getElementById("hangup-button").disabled = true; } } /* 处理来自指定用户的挂断消息 */ function handleHangUpMsg(msg) { const senderUsername = msg.name; log(`*** Received hang up notification from ${senderUsername}`); closeVideoCall(senderUsername); } /* 挂断与指定用户的通话 */ function hangUpCall(targetUsername) { if (!targetUsername || !peerConnections[targetUsername]) return; closeVideoCall(targetUsername); sendToServer({ name: myUsername, target: targetUsername, type: "hang-up" }); this.targetUsername = null; }
配套调整说明
- 建立连接时:不要把新创建的
RTCPeerConnection赋值给单个变量,而是存入peerConnections[目标用户名],同时执行activeConnectionsCount++ - 界面交互:挂断按钮需要明确针对当前选中的用户(比如点击某个用户的视频窗口后,挂断按钮仅对该用户生效),或者给每个用户的视频窗口单独添加挂断按钮
内容的提问来源于stack exchange,提问作者Mansour Shahabinezhad
相关产品推荐
相关产品推荐

