fix(webrtc): rebuild the RTCPeerConnection on failure instead of restartIce()

"restarting ICE" on a connection that has reached 'failed' only restarts
ICE gathering — it reuses the same DTLS transport and certificate. If
that transport is what's actually broken, the next renegotiation throws
"Failed to set SSL role for the transport" (DTLS role can't be flipped
on an established transport), which is exactly what showed up in the
console on a LAN test, ruling out NAT/TURN as the cause.

Fix: on 'failed', fully close and recreate the RTCPeerConnection (fresh
certificate, nothing to conflict with) via recreatePeerConnection().
Since ICE/DTLS failure isn't guaranteed to fire on both ends at once,
the side that notices sends a new 'reset' signal (relayed by the
server like offer/answer/candidate) telling the other side to tear
down and wait for a fresh offer too — otherwise its old, now-mismatched
transport would just fail the same way against our new one. Capped at
3 rebuild attempts per peer before giving up with a toast, reset on any
successful 'connected' state.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
matsandClaude Sonnet 5 committed 2026-09-22 12:08:07 +02:00
1 parent 8474a85ed2
commit 3517bdf52b
2 files changed
+50 -3

No files matched your search

+2 -1
View File
@@ -240,7 +240,8 @@ wss.on('connection', (socket, req) => {
}
case 'offer':
case 'answer':
case 'candidate': {
case 'candidate':
case 'reset': {
if (!msg.to || !room.has(msg.to)) return;
const target = room.get(msg.to);
if (target.socket.readyState === 1) {