zebra-report: surface media path (direct P2P vs relayed via TURN)
This commit is contained in:
parent
0a218c1a09
commit
a995c8a711
1 changed files with 35 additions and 0 deletions
|
|
@ -263,6 +263,10 @@
|
|||
<span id="rtc-status" class="note">peer link: idle</span>
|
||||
<button id="btn-reset-rtc" style="margin-left:auto">reset</button>
|
||||
</div>
|
||||
<div class="row" style="margin-top:0.3rem">
|
||||
<div class="dot" id="dot-path"></div>
|
||||
<span id="path-status" class="status-line">path: not connected</span>
|
||||
</div>
|
||||
<p class="note" style="margin-top:0.5rem">
|
||||
both peers type the same code; SDP is exchanged automatically via the relay
|
||||
(encrypted with the code). chat content rides the audio carrier.
|
||||
|
|
@ -1171,8 +1175,10 @@ function ensurePC() {
|
|||
dotRtc.className = 'dot ok';
|
||||
logLine('sys', 'webrtc connected');
|
||||
announceHello().catch(() => {});
|
||||
setTimeout(reportTransport, 1200);
|
||||
} else if (s === 'failed' || s === 'closed' || s === 'disconnected') {
|
||||
dotRtc.className = 'dot';
|
||||
setPath('path: not connected', null);
|
||||
logLine('err', `webrtc ${s} — click "reset connection" then retry`);
|
||||
}
|
||||
};
|
||||
|
|
@ -1182,6 +1188,34 @@ function ensurePC() {
|
|||
return pc;
|
||||
}
|
||||
|
||||
function setPath(msg, kind) {
|
||||
const el = $('path-status'); if (el) { el.textContent = msg; el.className = 'status-line' + (kind ? ' ' + kind : ''); }
|
||||
const dot = $('dot-path'); if (dot) dot.className = 'dot' + (kind === 'ok' ? ' ok' : kind === 'err' ? ' warn' : '');
|
||||
}
|
||||
/* Read the live ICE candidate pair so users can see whether anything sits
|
||||
* between them: a direct host/srflx pair = peer-to-peer, nobody in the audio
|
||||
* path; a 'relay' candidate = the TURN server is forwarding their (encrypted)
|
||||
* audio. */
|
||||
async function reportTransport() {
|
||||
if (!pc) return;
|
||||
try {
|
||||
const stats = await pc.getStats();
|
||||
let pair = null;
|
||||
stats.forEach(r => { if (r.type === 'candidate-pair' && r.nominated && r.state === 'succeeded') pair = r; });
|
||||
if (!pair) stats.forEach(r => { if (!pair && r.type === 'candidate-pair' && r.state === 'succeeded') pair = r; });
|
||||
if (!pair) { setPath('path: connecting…', null); return; }
|
||||
const loc = stats.get(pair.localCandidateId) || {}, rem = stats.get(pair.remoteCandidateId) || {};
|
||||
const relayed = loc.candidateType === 'relay' || rem.candidateType === 'relay';
|
||||
if (relayed) {
|
||||
setPath('path: RELAYED through TURN (proxy.uncloseai.com sees encrypted audio)', 'err');
|
||||
logLine('sys', 'transport: relayed via TURN — a server is in the path (audio stays encrypted)');
|
||||
} else {
|
||||
setPath(`path: DIRECT peer-to-peer — nobody between you (${loc.candidateType || '?'}/${rem.candidateType || '?'})`, 'ok');
|
||||
logLine('sys', `transport: direct peer-to-peer (${loc.candidateType || '?'}/${rem.candidateType || '?'})`);
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
function resetConnection() {
|
||||
if (typeof disconnectRelay === 'function') disconnectRelay();
|
||||
if (pc) {
|
||||
|
|
@ -1195,6 +1229,7 @@ function resetConnection() {
|
|||
rxDecoders.clear();
|
||||
rtcStatus.textContent = 'peer link: idle';
|
||||
dotRtc.className = 'dot warn';
|
||||
setPath('path: not connected', null);
|
||||
logLine('sys', 'connection reset — ready to retry');
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue