PeerJS如何关闭特定peer id连接且不销毁全局Peer实例?
实现方案
你不需要销毁整个Peer实例,也不需要每次匹配后重建Peer,PeerJS的单个点对点连接对应MediaConnection实例(也就是你代码里的call对象),只要主动关闭对应MediaConnection即可实现仅断开指定远端用户的效果,具体修改步骤如下:
步骤1:修改全局存储结构
你当前仅存储了远端peer_id列表,需要调整为同时存储每个peer_id对应的MediaConnection实例,方便后续查找并关闭连接:
var OURSTRAM; // 改为对象结构,key为远端peer_id,value为对应的call实例 const CurrentPeers = {}; var peer; io = io.connect();
步骤2:在建立连接时存储call实例
分别修改呼入、呼出场景的代码,将call实例存入CurrentPeers:
修改呼入处理逻辑
function init_peer(){ peer = new Peer({ config: {'iceServers': 'iceServersList' } }); peer.on('open', function(id) { io.emit('ready' , { peer_id : id }); }); peer.on('call' , function (call) { call.answer(OURSTRAM); // 存储call实例 CurrentPeers[call.peer] = call; call.on('stream' , function(remoteStream){ addRemoteVideo(remoteStream , call.peer , 'oncall'); }) // 监听连接关闭事件,自动清理资源 call.on('close', () => { delete CurrentPeers[call.peer]; }) }) }
修改呼出处理逻辑
function callPeer(id) { let call = peer.call(id , OURSTRAM); // 存储call实例 CurrentPeers[id] = call; call.on('stream' , function(remoteStream) { addRemoteVideo(remoteStream , id , 'callPeer'); }); // 监听连接关闭事件,自动清理资源 call.on('close', () => { delete CurrentPeers[id]; }) }
步骤3:实现remove_peer事件的处理逻辑
收到信令服务器下发的remove_peer事件时,关闭对应连接、清理视频元素、释放资源:
io.on('remove_peer' , function(data){ const remotePeerId = data.remote_peer_id; // 检查是否存在对应连接 if(CurrentPeers[remotePeerId]){ // 关闭点对点连接 CurrentPeers[remotePeerId].close(); // 移除存储的call实例 delete CurrentPeers[remotePeerId]; // 清空远端视频元素 const remoteVideArea = $('#their-video')[0]; if(remoteVideArea.srcObject){ remoteVideArea.srcObject.getTracks().forEach(track => track.stop()); remoteVideArea.srcObject = null; } } console.log(`已移除peer ${remotePeerId}`); })
额外注意事项
- 如果你的场景支持3人同时聊天,需要调整视频渲染逻辑,给每个远端用户分配独立的video元素,不要共用同一个
#their-video - 无需每次匹配后重建Peer实例,Peer实例仅代表你的客户端在PeerJS信令网络中的身份标识,保留实例可以直接复用建立新连接,不需要重复执行初始化、上报peer_id的逻辑
- 如果需要彻底清理本地流可以调用
OURSTRAM.getTracks().forEach(track => track.stop()),但如果用户还要继续匹配聊天,不需要停本地流,后续新连接可以直接复用。
内容的提问来源于stack exchange,提问作者hretic
相关产品推荐
相关产品推荐

