diff --git a/receivers/common/web/TcpListenerService.ts b/receivers/common/web/TcpListenerService.ts index e686a0c..28d17a4 100644 --- a/receivers/common/web/TcpListenerService.ts +++ b/receivers/common/web/TcpListenerService.ts @@ -70,6 +70,7 @@ export class TcpListenerService { heartbeatRetries += 1; session.send(Opcode.Ping); + this.emitter.emit('ping', { id: connectionId }); } catch (e) { Main.logger.warn(`Error while pinging sender device ${socket.remoteAddress}:${socket.remotePort}.`, e); socket.destroy(); diff --git a/receivers/common/web/WebSocketListenerService.ts b/receivers/common/web/WebSocketListenerService.ts index 988de36..425c0bd 100644 --- a/receivers/common/web/WebSocketListenerService.ts +++ b/receivers/common/web/WebSocketListenerService.ts @@ -68,6 +68,7 @@ export class WebSocketListenerService { heartbeatRetries += 1; session.send(Opcode.Ping); + this.emitter.emit('ping', { id: connectionId }); } catch (e) { Main.logger.warn(`Error while pinging sender device ${socket.remoteAddress}:${socket.remotePort}.`, e); socket.destroy(); diff --git a/receivers/common/web/main/Preload.ts b/receivers/common/web/main/Preload.ts index c0902ca..7e8c06c 100644 --- a/receivers/common/web/main/Preload.ts +++ b/receivers/common/web/main/Preload.ts @@ -18,20 +18,15 @@ if (TARGET === 'electron') { // @ts-ignore const electronAPI = __non_webpack_require__('electron'); - // Since event is sent async during window startup, could fire off before or after renderer.js is loaded - electronAPI.ipcRenderer.on('startup-storage-clear', () => { - localStorage.clear(); - }); - electronAPI.ipcRenderer.on("device-info", (_event, value: any) => { preloadData.deviceInfo = value; }) electronAPI.contextBridge.exposeInMainWorld('targetAPI', { - onStartupStorageClear: (callback: any) => electronAPI.ipcRenderer.on('startup-storage-clear', callback), onDeviceInfo: (callback: any) => electronAPI.ipcRenderer.on("device-info", callback), onConnect: (callback: any) => electronAPI.ipcRenderer.on("connect", callback), onDisconnect: (callback: any) => electronAPI.ipcRenderer.on("disconnect", callback), + onPing: (callback: any) => electronAPI.ipcRenderer.on("ping", callback), getDeviceInfo: () => preloadData.deviceInfo, }); @@ -39,17 +34,17 @@ if (TARGET === 'electron') { } else if (TARGET === 'webOS') { try { preloadData = { - onStartupStorageClearCb: () => { localStorage.clear(); }, onDeviceInfoCb: () => { console.log('Main: Callback not set while fetching device info'); }, onConnectCb: (_, value: any) => { console.log('Main: Callback not set while calling onConnect'); }, onDisconnectCb: (_, value: any) => { console.log('Main: Callback not set while calling onDisconnect'); }, + onPingCb: (_, value: any) => { console.log('Main: Callback not set while calling onPing'); }, }; window.targetAPI = { - onStartupStorageClear: (callback: () => void) => preloadData.onStartupStorageClearCb = callback, onDeviceInfo: (callback: () => void) => preloadData.onDeviceInfoCb = callback, onConnect: (callback: (_, value: any) => void) => preloadData.onConnectCb = callback, onDisconnect: (callback: (_, value: any) => void) => preloadData.onDisconnectCb = callback, + onPing: (callback: (_, value: any) => void) => preloadData.onPingCb = callback, getDeviceInfo: () => preloadData.deviceInfo, }; } diff --git a/receivers/common/web/main/Renderer.ts b/receivers/common/web/main/Renderer.ts index 554f270..db3f64b 100644 --- a/receivers/common/web/main/Renderer.ts +++ b/receivers/common/web/main/Renderer.ts @@ -6,22 +6,19 @@ import { toast, ToastIcon } from '../components/Toast'; const connectionStatusText = document.getElementById("connection-status-text"); const connectionStatusSpinner = document.getElementById("connection-spinner"); const connectionStatusCheck = document.getElementById("connection-check"); -let connections = JSON.parse(localStorage.getItem('connections')) ?? []; -if (connections.length > 0) { - connections.forEach(connection => { - onConnect(connection); - }); -} +let connections = []; -window.targetAPI.onStartupStorageClear((_event, value: any) => { - localStorage.clear(); - localStorage.setItem('connections', JSON.stringify(connections)); +// Window might be re-created while devices are still connected +window.targetAPI.onPing((_event, value: any) => { + if (connections.length === 0) { + connections.push(value.id); + onConnect(value.id); + } }); window.targetAPI.onDeviceInfo(renderIPsAndQRCode); window.targetAPI.onConnect((_event, value: any) => { connections.push(value.id); - localStorage.setItem('connections', JSON.stringify(connections)); onConnect(value); }); window.targetAPI.onDisconnect((_event, value: any) => { @@ -29,7 +26,6 @@ window.targetAPI.onDisconnect((_event, value: any) => { const index = connections.indexOf(value.id); if (index != -1) { connections.splice(index, 1); - localStorage.setItem('connections', JSON.stringify(connections)); } if (connections.length === 0) { diff --git a/receivers/electron/src/Main.ts b/receivers/electron/src/Main.ts index 6c71633..3548d1e 100644 --- a/receivers/electron/src/Main.ts +++ b/receivers/electron/src/Main.ts @@ -25,7 +25,6 @@ export class Main { static discoveryService: DiscoveryService; static tray: Tray; static logger: log4js.Logger; - private static startupStorageClear = true; private static toggleMainWindow() { if (Main.mainWindow) { @@ -194,6 +193,7 @@ export class Main { l.emitter.on('connect', (message) => Main.mainWindow?.webContents?.send('connect', message)); l.emitter.on('disconnect', (message) => Main.mainWindow?.webContents?.send('disconnect', message)); + l.emitter.on('ping', (message) => Main.mainWindow?.webContents?.send('ping', message)); l.start(); ipcMain.on('send-playback-error', (event: IpcMainEvent, value: PlaybackErrorMessage) => { @@ -298,11 +298,6 @@ export class Main { } }); - if (Main.startupStorageClear) { - Main.mainWindow.webContents.send('startup-storage-clear'); - Main.startupStorageClear = false; - } - Main.mainWindow.loadFile(path.join(__dirname, 'main/index.html')); Main.mainWindow.on('closed', () => { Main.mainWindow = null; diff --git a/receivers/webos/fcast-receiver-service/src/Main.ts b/receivers/webos/fcast-receiver-service/src/Main.ts index a59fbf8..1c06e49 100644 --- a/receivers/webos/fcast-receiver-service/src/Main.ts +++ b/receivers/webos/fcast-receiver-service/src/Main.ts @@ -49,21 +49,6 @@ export class Main { const voidCb = (message: any) => { message.respond({ returnValue: true, value: {} }); }; const objectCb = (message: any, value: any) => { message.respond({ returnValue: true, value: value }); }; - let startupStorageClearClosureCb = null; - service.register("startup-storage-clear", (message: any) => { - if (message.isSubscription) { - startupStorageClearClosureCb = voidCb.bind(this, message); - Main.emitter.on('startup-storage-clear', startupStorageClearClosureCb); - } - - message.respond({ returnValue: true, value: { subscribed: true }}); - }, - (message: any) => { - Main.logger.info('Canceled startup-storage-clear service subscriber'); - Main.emitter.off('startup-storage-clear', startupStorageClearClosureCb); - message.respond({ returnValue: true, value: message.payload }); - }); - let toastClosureCb = null; service.register("toast", (message: any) => { if (message.isSubscription) { @@ -118,6 +103,21 @@ export class Main { message.respond({ returnValue: true, value: message.payload }); }); + let pingClosureCb = null; + service.register("ping", (message: any) => { + if (message.isSubscription) { + pingClosureCb = objectCb.bind(this, message); + Main.emitter.on('ping', pingClosureCb); + } + + message.respond({ returnValue: true, value: { subscribed: true }}); + }, + (message: any) => { + Main.logger.info('Canceled ping service subscriber'); + Main.emitter.off('ping', pingClosureCb); + message.respond({ returnValue: true, value: message.payload }); + }); + Main.discoveryService = new DiscoveryService(); Main.discoveryService.start(); @@ -272,6 +272,7 @@ export class Main { l.emitter.on('connect', (message) => Main.emitter.emit('connect', message)); l.emitter.on('disconnect', (message) => Main.emitter.emit('disconnect', message)); + l.emitter.on('ping', (message) => Main.emitter.emit('ping', message)); l.start(); }); @@ -303,8 +304,6 @@ export class Main { message.respond({ returnValue: true, value: { success: true } }); }); - - this.emitter.emit('startup-storage-clear'); } catch (err) { Main.logger.error("Error initializing service:", err); diff --git a/receivers/webos/fcast-receiver/src/main/Preload.ts b/receivers/webos/fcast-receiver/src/main/Preload.ts index cf834e2..ca3ad02 100644 --- a/receivers/webos/fcast-receiver/src/main/Preload.ts +++ b/receivers/webos/fcast-receiver/src/main/Preload.ts @@ -15,7 +15,6 @@ enum RemoteKeyCode { } try { - const startupStorageClearService = registerService('startup-storage-clear', () => { preloadData.onStartupStorageClearCb(); }); const toastService = registerService('toast', (message: any) => { toast(message.value.message, message.value.icon, message.value.duration); }); const getDeviceInfoService = registerService('getDeviceInfo', (message: any) => { console.log(`Main: getDeviceInfo ${JSON.stringify(message)}`); @@ -24,14 +23,15 @@ try { }, false); const onConnectService = registerService('connect', (message: any) => { preloadData.onConnectCb(null, message.value); }); const onDisconnectService = registerService('disconnect', (message: any) => { preloadData.onDisconnectCb(null, message.value); }); + const onPingService = registerService('ping', (message: any) => { preloadData.onPingCb(null, message.value); }); const playService = registerService('play', (message: any) => { if (message.value !== undefined && message.value.playData !== undefined) { console.log(`Main: Playing ${JSON.stringify(message)}`); getDeviceInfoService.cancel(); - startupStorageClearService.cancel(); toastService.cancel(); onConnectService.cancel(); onDisconnectService.cancel(); + onPingService.cancel(); playService.cancel(); // WebOS 22 and earlier does not work well using the history API, @@ -49,11 +49,11 @@ try { const lastTimestamp = localStorage.getItem('lastTimestamp'); if (params.playData !== undefined && params.timestamp != lastTimestamp) { localStorage.setItem('lastTimestamp', params.timestamp); - startupStorageClearService?.cancel(); toastService?.cancel(); getDeviceInfoService?.cancel(); onConnectService?.cancel(); onDisconnectService?.cancel(); + onPingService?.cancel(); playService?.cancel(); // WebOS 22 and earlier does not work well using the history API,