fix ice candidates
This commit is contained in:
1 parent
87f181504c
commit
9b8c2a9599
1 file changed
+32
-8
+32
-8
@@ -625,12 +625,19 @@ function handleSignal(msg) {
|
||||
toast(`Joined ${msg.room}`, 'ok');
|
||||
break;
|
||||
}
|
||||
case 'joined':
|
||||
S.peers.set(msg.peer.id, makePeerRecord(msg.peer));
|
||||
case 'joined': {
|
||||
// If candidates for this peer arrived before its description (orphan
|
||||
// record from the candidate handler), carry the buffer over instead of
|
||||
// dropping it with the old record.
|
||||
const prev = S.peers.get(msg.peer.id);
|
||||
const peer = makePeerRecord(msg.peer);
|
||||
if (prev?.pendingCandidates?.length) peer.pendingCandidates = prev.pendingCandidates;
|
||||
S.peers.set(msg.peer.id, peer);
|
||||
playRetroCue('join');
|
||||
renderAll();
|
||||
toast(`${msg.peer.name} joined`, 'ok');
|
||||
break;
|
||||
}
|
||||
case 'left': {
|
||||
const peer = S.peers.get(msg.id);
|
||||
if (peer) {
|
||||
@@ -662,8 +669,13 @@ function handleSignal(msg) {
|
||||
break;
|
||||
}
|
||||
case 'candidate': {
|
||||
const peer = S.peers.get(msg.from);
|
||||
if (!peer || !peer.pc) return; // candidates only after description path created pc
|
||||
// A candidate can legitimately arrive before its description is
|
||||
// applied: during a join storm the offer may still be inside
|
||||
// createOffer(), and after a 'reset' the pc is briefly null mid-rebuild.
|
||||
// Dropping those loses srflx/relay candidates the pair may have no
|
||||
// alternative for, so buffer them — onDescription() flushes
|
||||
// peer.pendingCandidates once the remote description lands.
|
||||
const peer = S.peers.get(msg.from) || createOrphanPeer(msg.from);
|
||||
onCandidate(peer, msg.candidate).catch((e) => {
|
||||
console.error('candidate failed', e);
|
||||
captureRumIssue('WebRTC ICE candidate failed', 'WARNING', { peerId: peer.id, error: e?.message || String(e) });
|
||||
@@ -674,9 +686,11 @@ function handleSignal(msg) {
|
||||
// The other side's connection to us failed and it's rebuilding from
|
||||
// scratch — tear down our half so a fresh offer lands on a clean
|
||||
// RTCPeerConnection instead of an already-established (and now
|
||||
// mismatched) DTLS transport. See recreatePeerConnection().
|
||||
// mismatched) DTLS transport, and count the failure toward the relay
|
||||
// fallback so both halves force TURN on the retry.
|
||||
// See recreatePeerConnection().
|
||||
const peer = S.peers.get(msg.from);
|
||||
if (peer) recreatePeerConnection(peer, { announce: false });
|
||||
if (peer) recreatePeerConnection(peer, { announce: false, remote: true });
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -864,7 +878,7 @@ const RESET_MAX_ATTEMPTS = 3;
|
||||
// failure first, whichever side detects it also tells the other to rebuild via
|
||||
// a 'reset' signal — otherwise the other side keeps its old, now-mismatched
|
||||
// transport and the fresh offer we send will fail against it too.
|
||||
function recreatePeerConnection(peer, { announce }) {
|
||||
function recreatePeerConnection(peer, { announce, remote = false }) {
|
||||
if (announce) {
|
||||
peer.resetAttempts++;
|
||||
if (peer.resetAttempts > RESET_MAX_ATTEMPTS) {
|
||||
@@ -876,6 +890,16 @@ function recreatePeerConnection(peer, { announce }) {
|
||||
return;
|
||||
}
|
||||
send({ type: 'reset', to: peer.id });
|
||||
} else if (remote) {
|
||||
// The far side detected 'failed' against us and is rebuilding. Count the
|
||||
// failure here too so our half ALSO recreates with
|
||||
// iceTransportPolicy:'relay' — before, only the detecting side forced
|
||||
// relay, so the other side kept retrying the same direct path that just
|
||||
// died and the pair burned rebuild rounds before converging.
|
||||
peer.resetAttempts++;
|
||||
if (peer.resetAttempts === RESET_MAX_ATTEMPTS + 1) {
|
||||
toast(`Connection to ${peer.name} keeps failing — TURN relay may be down`, 'error');
|
||||
}
|
||||
}
|
||||
if (peer.pc) { try { peer.pc.close(); } catch {} }
|
||||
if (peer.qualityTimer) { clearInterval(peer.qualityTimer); peer.qualityTimer = null; }
|
||||
@@ -915,7 +939,7 @@ async function onDescription(peer, desc) {
|
||||
|
||||
async function onCandidate(peer, candidate) {
|
||||
if (peer.ignoreOffer) return;
|
||||
if (!peer.pc.remoteDescription) {
|
||||
if (!peer.pc || !peer.pc.remoteDescription) { // no pc yet: orphan peer mid-join or mid-rebuild
|
||||
peer.pendingCandidates.push(candidate);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user