From 8b265ecf71470eb11c8c1cde7a9a3cae4d625f1b Mon Sep 17 00:00:00 2001 From: Amateur Audio Dude <168192910+AmateurAudioDude@users.noreply.github.com> Date: Mon, 23 Sep 2024 17:48:16 +1000 Subject: [PATCH 1/4] serialport reconnect rework - v1.3.0.1 --- web/js/main.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/web/js/main.js b/web/js/main.js index bcae21e..f9463b0 100644 --- a/web/js/main.js +++ b/web/js/main.js @@ -184,7 +184,7 @@ $(document).ready(function () { //FMLIST logging $('#log-fmlist').on('click', function() { - console.log('asdfdasf'); + //console.log('FMLIST'); $.ajax({ url: './log_fmlist', method: 'GET', @@ -284,6 +284,18 @@ function sendPingRequest() { console.warn("Main/UI WebSocket closed during reconnection. Will attempt to reconnect..."); }; } + if (connectionLost) { + if (dataTimeout == dataTimeoutPrevious) { + connectionLost = true; + } else { + setTimeout(() => { + window.socket.close(1000, 'Normal closure'); // Force reconnection to unfreeze browser UI + }, 8000); // Timeout must be higher than TIMEOUT_DURATION + connectionLost = false; + requiresAudioStreamRestart = true; + console.log("Radio data restored."); + } + } } // Automatic UI resume on WebSocket reconnect @@ -298,7 +310,9 @@ function handleWebSocketMessage(event) { parsedData = JSON.parse(event.data); + resetDataTimeout(); updatePanels(parsedData); + const sum = signalData.reduce((acc, strNum) => acc + parseFloat(strNum), 0); const averageSignal = sum / signalData.length; data.push(averageSignal); @@ -455,12 +469,18 @@ function updateCanvas(parsedData, signalChart) { let reconnectTimer = null; let dataTimeout = null; +let dataTimeoutPrevious = null; +let connectionLost = false; +let requiresAudioStreamRestart = false; + const TIMEOUT_DURATION = 5000; // 5 seconds timeout for lost connection const resetDataTimeout = () => { clearTimeout(dataTimeout); dataTimeout = setTimeout(() => { sendToast('warning', 'Connection lost', 'Attempting to reconnect...', false, false); + connectionLost = true; + dataTimeoutPrevious = dataTimeout; }, TIMEOUT_DURATION); }; From a7931257d5fdb5342b3a28764c106e1e2a0a24b8 Mon Sep 17 00:00:00 2001 From: Amateur Audio Dude <168192910+AmateurAudioDude@users.noreply.github.com> Date: Mon, 23 Sep 2024 17:48:46 +1000 Subject: [PATCH 2/4] serialport reconnect rework - v1.3.0.1 --- web/js/3las/3las.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/web/js/3las/3las.js b/web/js/3las/3las.js index 23490f5..b705064 100644 --- a/web/js/3las/3las.js +++ b/web/js/3las/3las.js @@ -1,3 +1,4 @@ +var audioStreamRestartInterval; var elapsedTimeConnectionWatchdog; var _3LAS_Settings = /** @class */ (function () { function _3LAS_Settings() { @@ -48,6 +49,20 @@ var _3LAS = /** @class */ (function () { this.ConnectivityFlag = false; this.Stop(); // Attempt to mitigate the 0.5x speed/multiple stream bug + // Restart audio stream if radio data connection was reestablished + // to prevent stuttering audio in some cases + if (audioStreamRestartInterval) { + clearInterval(audioStreamRestartInterval); + } + audioStreamRestartInterval = setInterval(() => { + if (requiresAudioStreamRestart) { + requiresAudioStreamRestart = false; + this.Stop(); + this.Start(); + console.log("Audio stream restarted after radio data loss."); + } + }, 3000); + // Stream connection watchdog monitors mp3 frames console.log("Stream connection watchdog active."); let intervalReconnectWatchdog = setInterval(() => { From b4047cbabb9efa716c6dbc3e3c2ebedfe8c4e746 Mon Sep 17 00:00:00 2001 From: Amateur Audio Dude <168192910+AmateurAudioDude@users.noreply.github.com> Date: Mon, 23 Sep 2024 17:49:01 +1000 Subject: [PATCH 3/4] serialport reconnect rework - v1.3.0.1 --- server/datahandler.js | 12 ++++++++++++ server/index.js | 27 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/server/datahandler.js b/server/datahandler.js index 4b0f16a..34b6644 100644 --- a/server/datahandler.js +++ b/server/datahandler.js @@ -425,6 +425,18 @@ function handleData(wss, receivedData, rdsWss) { } } +// Serialport retry code when port is open but communication is lost (additional code in index.js) +isSerialportAlive = true; +lastFrequencyAlive = '87.500'; +setInterval(() => { + lastFrequencyAlive = initialData.freq; + // Activate serialport retry if handleData has not been executed for over 10 seconds + if (((Date.now() - lastUpdateTime) > 8000) && !isSerialportRetrying && serverConfig.xdrd.wirelessConnection === false) { + isSerialportAlive = false; + isSerialportRetrying = true; + } +}, 2000); + function showOnlineUsers(currentUsers) { dataToSend.users = currentUsers; initialData.users = currentUsers; diff --git a/server/index.js b/server/index.js index fa0742d..449664d 100644 --- a/server/index.js +++ b/server/index.js @@ -126,6 +126,28 @@ function checkIPv6Support(callback) { }); } +// Serialport retry code when port is open but communication is lost (additional code in datahandler.js) +isSerialportRetrying = false; + +setInterval(() => { + if (!isSerialportAlive && serverConfig.xdrd.wirelessConnection === false) { + isSerialportAlive = true; + isSerialportRetrying = true; + if (serialport && serialport.isOpen) { + logWarn('Communication lost from ' + serverConfig.xdrd.comPort + ', force closing serialport.'); + setTimeout(() => { + serialport.close((err) => { + if (err) { + logError('Error closing serialport: ', err.message); + } + }); + }, 1000); + } else { + logWarn('Communication lost from ' + serverConfig.xdrd.comPort + '.'); + } + } +}, 2000); + // Serial Connection function connectToSerial() { if (serverConfig.xdrd.wirelessConnection === false) { @@ -150,6 +172,7 @@ if (serverConfig.xdrd.wirelessConnection === false) { } logInfo('Using COM device: ' + serverConfig.xdrd.comPort); + isSerialportAlive = true; setTimeout(() => { serialport.write('x\n'); }, 3000); @@ -163,9 +186,12 @@ if (serverConfig.xdrd.wirelessConnection === false) { serialport.write('T' + Math.round(serverConfig.defaultFreq * 1000) + '\n'); dataHandler.initialData.freq = Number(serverConfig.defaultFreq).toFixed(3); dataHandler.dataToSend.freq = Number(serverConfig.defaultFreq).toFixed(3); + } else if (lastFrequencyAlive && isSerialportRetrying) { // Serialport retry code when port is open but communication is lost + serialport.write('T' + (lastFrequencyAlive * 1000) + '\n'); } else { serialport.write('T87500\n'); } + isSerialportRetrying = false; serialport.write('A0\n'); serialport.write('F-1\n'); @@ -190,6 +216,7 @@ if (serverConfig.xdrd.wirelessConnection === false) { serialport.on('close', () => { logWarn('Disconnected from ' + serverConfig.xdrd.comPort + '. Attempting to reconnect.'); setTimeout(() => { + isSerialportRetrying = true; connectToSerial(); }, 5000); }); From 2068eb8f6a9375454b6e4385185279aaea57a25b Mon Sep 17 00:00:00 2001 From: Amateur Audio Dude <168192910+AmateurAudioDude@users.noreply.github.com> Date: Tue, 24 Sep 2024 17:26:31 +1000 Subject: [PATCH 4/4] serialport reconnect rework - v1.3.0.1 --- web/js/3las/3las.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/web/js/3las/3las.js b/web/js/3las/3las.js index b705064..5930aa2 100644 --- a/web/js/3las/3las.js +++ b/web/js/3las/3las.js @@ -57,9 +57,11 @@ var _3LAS = /** @class */ (function () { audioStreamRestartInterval = setInterval(() => { if (requiresAudioStreamRestart) { requiresAudioStreamRestart = false; - this.Stop(); - this.Start(); - console.log("Audio stream restarted after radio data loss."); + if (Stream) { + this.Stop(); + this.Start(); + console.log("Audio stream restarted after radio data loss."); + } } }, 3000);