如何通过WebRTC Offer结合PeerJS实现对等连接?
如何绕开PeerJS的Broker,用RTCPeerConnection的Offer直接建立对等连接
问题描述
我不想用PeerJS官方文档里的var conn = peer.connect('dest-peer-id');方式建立连接,希望直接通过WebRTC的Offer来创建对等连接。我注意到Peer对象暴露了底层的RTCPeerConnection,期望实现类似这样的逻辑:
// 计算机1端 let offer = await peer.RTCPeerConnection.createOffer() // 计算机2端 let conn = peer.connect({ offer }); // 或 let conn = peer.RTCPeerConnection.connect({ offer });
请问是否可以借助底层的RTCPeerConnection实现对等连接,且无需依赖Peer Broker?
回答
可以实现,但不能直接用你期望的peer.connect({ offer })语法——因为PeerJS的peer.connect方法本质依赖其内置信令Broker来交换连接信息。要绕开Broker,你需要手动利用底层RTCPeerConnection完成完整的信令交换流程,具体步骤如下:
1. 初始化Peer对象(可选禁用Broker连接)
如果完全不想依赖PeerJS的信令服务器,初始化Peer时可以跳过Broker连接,仅用它提供的RTCPeerConnection封装和ICE配置:
// 两端通用初始化代码 const peer = new Peer(null, { config: { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }, // 自定义ICE服务器 debug: 2 // 可选,用于调试 });
2. 计算机1端:生成Offer并发送
// 创建RTCPeerConnection实例 const pc1 = new peer.RTCPeerConnection(peer._options.config); // (可选)添加本地媒体流 const localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true }); localStream.getTracks().forEach(track => pc1.addTrack(track, localStream)); // 生成Offer并设置本地会话描述 const offer = await pc1.createOffer(); await pc1.setLocalDescription(offer); // 监听ICE候选,发送给计算机2(需自己实现信令通道,比如WebSocket/HTTP) pc1.onicecandidate = (event) => { if (event.candidate) { sendSignalingDataToComputer2({ type: 'ice', data: event.candidate }); } }; // 发送Offer到计算机2 sendSignalingDataToComputer2({ type: 'offer', data: offer });
3. 计算机2端:接收Offer并返回Answer
// 创建RTCPeerConnection实例 const pc2 = new peer.RTCPeerConnection(peer._options.config); // (可选)监听远程媒体流 pc2.ontrack = (event) => { const remoteStream = event.streams[0]; document.getElementById('remote-video').srcObject = remoteStream; }; // 监听ICE候选,发送给计算机1 pc2.onicecandidate = (event) => { if (event.candidate) { sendSignalingDataToComputer1({ type: 'ice', data: event.candidate }); } }; // 接收计算机1的Offer并处理 const incomingData = receiveSignalingDataFromComputer1(); if (incomingData.type === 'offer') { await pc2.setRemoteDescription(new RTCSessionDescription(incomingData.data)); // 生成Answer并设置本地会话描述 const answer = await pc2.createAnswer(); await pc2.setLocalDescription(answer); // 发送Answer到计算机1 sendSignalingDataToComputer1({ type: 'answer', data: answer }); }
4. 计算机1端:接收Answer并完成连接
// 接收计算机2的Answer并处理 const incomingData = receiveSignalingDataFromComputer2(); if (incomingData.type === 'answer') { await pc1.setRemoteDescription(new RTCSessionDescription(incomingData.data)); } // 接收并添加计算机2的ICE候选 if (incomingData.type === 'ice') { await pc1.addIceCandidate(new RTCIceCandidate(incomingData.data)); }
关键注意事项
- 绕开PeerJS Broker后,必须自己实现信令通道(用来传递Offer、Answer、ICE候选),PeerJS不会再帮你处理这部分逻辑。
peer.connect方法不支持直接传入Offer参数,它仅用于向PeerJS的Broker发起连接请求。- 必须严格遵循信令交换顺序:Offer → Answer → ICE候选交换,否则连接会失败。
内容的提问来源于stack exchange,提问作者X0r0N
相关产品推荐
相关产品推荐

