From 00b52dde8deb27d907cb2a35aaad7e366ee7b06b Mon Sep 17 00:00:00 2001 From: sergystepanov Date: Mon, 1 Jun 2026 18:11:41 +0300 Subject: [PATCH] Reformat webrtc.js --- web/js/network/webrtc.js | 167 ++++++++++++++++++++++----------------- 1 file changed, 94 insertions(+), 73 deletions(-) diff --git a/web/js/network/webrtc.js b/web/js/network/webrtc.js index 02d8da2d..b6418ca2 100644 --- a/web/js/network/webrtc.js +++ b/web/js/network/webrtc.js @@ -4,14 +4,14 @@ import { WEBRTC_CONNECTION_READY, WEBRTC_ICE_CANDIDATE_FOUND, WEBRTC_ICE_CANDIDATES_FLUSH, - WEBRTC_SDP_ANSWER -} from 'event'; -import {log} from 'log'; + WEBRTC_SDP_ANSWER, +} from "event"; +import { log } from "log"; let connection; -let dataChannel -let keyboardChannel -let mouseChannel +let dataChannel; +let keyboardChannel; +let mouseChannel; let mediaStream; let candidates = []; let isAnswered = false; @@ -27,60 +27,75 @@ const ice = (() => { let timeForIceGathering; return { - onIceCandidate: data => { + onIceCandidate: (data) => { if (!data.candidate) return; log.debug(`[rtc] [ice] local: ${data.candidate?.candidate}`); - pub(WEBRTC_ICE_CANDIDATE_FOUND, {candidate: data.candidate}) + pub(WEBRTC_ICE_CANDIDATE_FOUND, { candidate: data.candidate }); }, - onIceCandidateError: event => { - let {address, errorCode, errorText, url} = event; + onIceCandidateError: (event) => { + let { address, errorCode, errorText, url } = event; if (errorCode === 701) { - errorText = 'couldn\'t reach the server' + errorText = "couldn't reach the server"; } - log.debug(`[rtc] [ice] candidate error: ${address || ''} ${errorCode}: ${errorText} / ${url}`) + log.debug( + `[rtc] [ice] candidate error: ${address || ""} ${errorCode}: ${errorText} / ${url}`, + ); }, - onIceStateChange: event => { + onIceStateChange: (event) => { const t = event.target; - log.debug(`[rtc] [ice] state: ${t.iceGatheringState}`) + log.debug(`[rtc] [ice] state: ${t.iceGatheringState}`); switch (event.target.iceGatheringState) { - case 'gathering': + case "gathering": timeForIceGathering = setTimeout(() => { - log.warn(`[rtc] ice gathering was aborted due to timeout ${ICE_TIMEOUT}ms`); + log.warn( + `[rtc] ice gathering was aborted due to timeout ${ICE_TIMEOUT}ms`, + ); // sendCandidates(); }, ICE_TIMEOUT); break; - case 'complete': + case "complete": if (timeForIceGathering) { clearTimeout(timeForIceGathering); } } }, onIceConnectionStateChange: () => { - log.debug(`[rtc] [ice] connection state: ${connection.iceConnectionState}`); + log.debug( + `[rtc] [ice] connection state: ${connection.iceConnectionState}`, + ); switch (connection.iceConnectionState) { - case 'connected': + case "connected": connected = true; break; - case 'disconnected': - log.info(`[rtc] [ice] disconnected... ` + - `connection: ${connection.connectionState}, ice: ${connection.iceConnectionState}, ` + - `gathering: ${connection.iceGatheringState}, signalling: ${connection.signalingState}`) + case "disconnected": + log.info( + `[rtc] [ice] disconnected... ` + + `connection: ${connection.connectionState}, ice: ${connection.iceConnectionState}, ` + + `gathering: ${connection.iceGatheringState}, signalling: ${connection.signalingState}`, + ); connected = false; pub(WEBRTC_CONNECTION_CLOSED); break; - case 'failed': - log.error('[rtc] [ice] failed establish connection, retry...'); + case "failed": + log.error( + "[rtc] [ice] failed establish connection, retry...", + ); connected = false; - connection.createOffer({iceRestart: true}) - .then(description => connection.setLocalDescription(description).catch(log.error)) + connection + .createOffer({ iceRestart: true }) + .then((description) => + connection + .setLocalDescription(description) + .catch(log.error), + ) .catch(log.error); break; } - } - } + }, + }; })(); /** @@ -88,80 +103,84 @@ const ice = (() => { */ export const webrtc = { start: (iceServers = []) => { - log.debug('[rtc] got remote ICE servers', iceServers); - connection = new RTCPeerConnection({iceServers: iceServers}); + log.debug("[rtc] got remote ICE servers", iceServers); + connection = new RTCPeerConnection({ iceServers: iceServers }); mediaStream = new MediaStream(); - connection.ondatachannel = e => { - log.debug(`[rtc] [data-ch] push: ${e.channel.label}`) + connection.ondatachannel = (e) => { + log.debug(`[rtc] [data-ch] push: ${e.channel.label}`); e.channel.binaryType = "arraybuffer"; - if (e.channel.label === 'keyboard') { - keyboardChannel = e.channel - return + if (e.channel.label === "keyboard") { + keyboardChannel = e.channel; + return; } - if (e.channel.label === 'mouse') { - mouseChannel = e.channel - return + if (e.channel.label === "mouse") { + mouseChannel = e.channel; + return; } dataChannel = e.channel; dataChannel.onopen = () => { - log.debug('[rtc] [data-ch] input channel has been opened'); + log.debug("[rtc] [data-ch] input channel has been opened"); inputReady = true; - pub(WEBRTC_CONNECTION_READY) + pub(WEBRTC_CONNECTION_READY); }; if (onData) { dataChannel.onmessage = onData; } dataChannel.onclose = () => { - inputReady = false - log.debug('[rtc] [data-ch] input channel has been closed') - } - } + inputReady = false; + log.debug("[rtc] [data-ch] input channel has been closed"); + }; + }; connection.oniceconnectionstatechange = ice.onIceConnectionStateChange; connection.onicegatheringstatechange = ice.onIceStateChange; connection.onicecandidate = ice.onIceCandidate; connection.onicecandidateerror = ice.onIceCandidateError; - connection.onconnectionstatechange = _ => { - console.debug(`[rtc] connection state: ${connection.connectionState}`) - } - connection.ontrack = event => { + connection.onconnectionstatechange = (_) => { + console.debug( + `[rtc] connection state: ${connection.connectionState}`, + ); + }; + connection.ontrack = (event) => { mediaStream.addTrack(event.track); - } + }; }, setRemoteDescription: async (sdp, media) => { - log.debug('[rtc] [sdp] remote offer', sdp) + log.debug("[rtc] [sdp] remote offer", sdp); try { const offer = new RTCSessionDescription(sdp); await connection.setRemoteDescription(offer); } catch (e) { - log.error(`[rtc] [sdp] remote offer error: ${e}`) + log.error(`[rtc] [sdp] remote offer error: ${e}`); } - log.debug(`[rtc] [sdp] remote Trickle ICE support: ${connection.canTrickleIceCandidates}`) + log.debug( + `[rtc] [sdp] remote Trickle ICE support: ${connection.canTrickleIceCandidates}`, + ); try { const answer = await connection.createAnswer(); // Chrome bug https://bugs.chromium.org/p/chromium/issues/detail?id=818180 workaround // force stereo params for Opus tracks (a=fmtp:111 ...) - answer.sdp = answer.sdp.replace(/(a=fmtp:111 .*)/g, '$1;stereo=1'); + answer.sdp = answer.sdp.replace(/(a=fmtp:111 .*)/g, "$1;stereo=1"); await connection.setLocalDescription(answer); - log.debug("[rtc] [sdp] local answer", answer) + log.debug("[rtc] [sdp] local answer", answer); isAnswered = true; pub(WEBRTC_ICE_CANDIDATES_FLUSH); - pub(WEBRTC_SDP_ANSWER, {sdp: answer}); + pub(WEBRTC_SDP_ANSWER, { sdp: answer }); } catch (e) { - log.error(`[rtc] [sdp] local answer error: ${e}`) + log.error(`[rtc] [sdp] local answer error: ${e}`); } media.srcObject = mediaStream; }, addCandidate: (data) => { - if (data === '') { + if (data === "") { pub(WEBRTC_ICE_CANDIDATES_FLUSH); } else { candidates.push(data); @@ -171,12 +190,14 @@ export const webrtc = { if (isFlushing || !isAnswered) return; isFlushing = true; if (log.level >= log.DEBUG) { - log.debug(`[rtc] [ice] set local candidates (${candidates.length}): ${candidates.map(c => c.candidate)}`) + log.debug( + `[rtc] [ice] set local candidates (${candidates.length}): ${candidates.map((c) => c.candidate)}`, + ); } let data = undefined; while (typeof (data = candidates.shift()) !== "undefined") { - connection.addIceCandidate(new RTCIceCandidate(data)).catch(e => { - log.error('[rtc] candidate add failed', e.name); + connection.addIceCandidate(new RTCIceCandidate(data)).catch((e) => { + log.error("[rtc] candidate add failed", e.name); }); } isFlushing = false; @@ -188,11 +209,11 @@ export const webrtc = { isInputReady: () => inputReady, stats: async () => { if (!connected) return Promise.resolve(); - return await connection.getStats() + return await connection.getStats(); }, stop: () => { if (mediaStream) { - mediaStream.getTracks().forEach(t => { + mediaStream.getTracks().forEach((t) => { t.stop(); mediaStream.removeTrack(t); }); @@ -203,21 +224,21 @@ export const webrtc = { connection = null; } if (dataChannel) { - dataChannel.close() - dataChannel = null + dataChannel.close(); + dataChannel = null; } if (keyboardChannel) { - keyboardChannel?.close() - keyboardChannel = null + keyboardChannel?.close(); + keyboardChannel = null; } if (mouseChannel) { - mouseChannel?.close() - mouseChannel = null + mouseChannel?.close(); + mouseChannel = null; } candidates = []; - log.info('[rtc] WebRTC has been closed'); + log.info("[rtc] WebRTC has been closed"); }, set onData(fn) { - onData = fn - } -} + onData = fn; + }, +};