From e3e68e8ea1d8d3779a8b149ad296266064d57386 Mon Sep 17 00:00:00 2001 From: Xin Wang Date: Tue, 21 Jul 2026 23:42:28 +0800 Subject: [PATCH] Add credentialed TURN server handling and update RTC configuration to gather direct, STUN, and TURN candidates. Enhance peer connection management with new credentials parameter. --- www/js/main.js | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/www/js/main.js b/www/js/main.js index 61e3cac..9270981 100644 --- a/www/js/main.js +++ b/www/js/main.js @@ -14,9 +14,8 @@ const $self = { rtcConfig: { - // WebRTC has no "STUN-only" transport policy. Using `all` with only - // STUN servers configured allows host and server-reflexive candidates, - // while ensuring that no TURN relay candidate can be created. + // Gather direct, STUN, and TURN candidates. ICE prefers direct/STUN + // candidate pairs and falls back to TURN when those checks fail. iceTransportPolicy: 'all', iceServers: [ { urls: 'stun:stun.l.google.com:19302' }, @@ -629,10 +628,15 @@ function handleScConnect() { console.log(`Self ID: ${$self.id}`); } -function handleScConnectedPeers({ peers }) { +function handleScConnectedPeers({ peers, credentials }) { const ids = peers; console.log(`Connected peer IDs: ${ids.join(', ')}`); + addCredentialedTurnServer([ + 'turn:182.92.86.220:3478?transport=udp', + 'turn:182.92.86.220:3478?transport=tcp', + ], credentials); + for (let id of ids) { if (id === $self.id) continue; // be polite with already-connected peers @@ -736,6 +740,29 @@ async function handleScSignal({ sender, * Utility Functions */ +function addCredentialedTurnServer(server_urls, { username, password }) { + // Add TURN after the STUN entries. ICE will still gather all candidate + // types, but direct and server-reflexive pairs have higher priority than + // relayed pairs under the standard ICE candidate priority rules. + const turn_server = { + urls: server_urls, + username: username, + credential: password, + }; + + const existing_index = $self.rtcConfig.iceServers.findIndex(server => + Array.isArray(server.urls) + && server.urls.some(url => server_urls.includes(url))); + + // Refresh the expiring credentials when the signaling channel reconnects + // instead of accumulating duplicate TURN entries. + if (existing_index >= 0) { + $self.rtcConfig.iceServers[existing_index] = turn_server; + } else { + $self.rtcConfig.iceServers.push(turn_server); + } +} + function prepareNamespace(hash, set_location) { let ns = hash.replace(/^#/, ''); // remove # from the hash if (/^[a-z]{4}-[a-z]{4}-[a-z]{4}$/.test(ns)) {