From ab990caca4f06d87399f8ff8f66c664beeb60591 Mon Sep 17 00:00:00 2001 From: garrettmills Date: Tue, 10 Nov 2020 10:39:22 -0600 Subject: [PATCH] Improve offline/online detection --- src/app/service/api.service.ts | 108 ++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 16 deletions(-) diff --git a/src/app/service/api.service.ts b/src/app/service/api.service.ts index b32cb6d..9a5a14d 100644 --- a/src/app/service/api.service.ts +++ b/src/app/service/api.service.ts @@ -45,27 +45,103 @@ export class ApiService { protected db: DatabaseService, protected connection: ConnectionService, ) { - connection.monitor().subscribe(isConnected => { - if ( !isConnected ) { - this.makeOffline(); - } else { - this.checkOnline().then(isOnline => { - if ( isOnline ) { - this.makeOnline(); - } else { - this.makeOffline(); + this.startOfflineObserver(); + } + + protected stopOfflineObserverClosure?: any; + + public stopOfflineObserver() { + if ( this.stopOfflineObserverClosure ) { + this.stopOfflineObserverClosure(); + } + } + + protected startOfflineObserver() { + const passiveCheckTime = 5; + const checkTimes = [5, 5, 10, 10, 15, 15, 20, 20, 30, 30, 30, 60, 60, 500]; + let currentCheckTimeIndex = 0; + let hasNetConnection = true; + let hasServerConnection = true; + let online = true; + let passiveCheckInterval; + let activeCheckInterval; + let stopped = false; + + this.stopOfflineObserverClosure = () => { + stopped = true; + clearInterval(passiveCheckInterval); + clearInterval(activeCheckInterval); + }; + + const checkServerConnection = async () => { + if ( !hasNetConnection ) { + return false; + } + + return this.checkOnline(); + }; + + const startPassiveCheck = () => { + passiveCheckInterval = setInterval(async () => { + if ( hasNetConnection ) { + const server = await checkServerConnection(); + if ( server !== hasServerConnection ) { + hasServerConnection = server; + await handleNetConnectionEvent(); } - }); + } + }, passiveCheckTime * 1000); + }; + + const doActiveCheck = async () => { + if ( activeCheckInterval ) { + clearInterval(activeCheckInterval); + if ( currentCheckTimeIndex < (checkTimes.length - 1) ) { + currentCheckTimeIndex += 1; + } } - }); - this.checkOnline().then(isConnected => { - if ( !isConnected ) { - this.makeOffline(); - } else { - this.makeOnline(); + if ( hasNetConnection ) { + const server = await checkServerConnection(); + if ( server !== hasServerConnection ) { + hasServerConnection = server; + await handleNetConnectionEvent(); + } else { + if ( activeCheckInterval ) { + activeCheckInterval = setInterval(doActiveCheck, checkTimes[currentCheckTimeIndex] * 1000); + } + } + } + }; + + const handleNetConnectionEvent = async () => { + if ( stopped ) { + return; } + + if ( online && (!hasNetConnection || !hasServerConnection) ) { + online = false; + await this.makeOffline(); + clearInterval(passiveCheckInterval); + activeCheckInterval = setInterval(doActiveCheck, checkTimes[currentCheckTimeIndex] * 1000); + } else if ( !online && (hasNetConnection && hasServerConnection) ) { + if ( activeCheckInterval ) { + clearInterval(activeCheckInterval); + } + + online = true; + currentCheckTimeIndex = 0; + await this.makeOnline(); + startPassiveCheck(); + } + }; + + this.connection.monitor().subscribe(isConnected => { + hasNetConnection = isConnected; + handleNetConnectionEvent(); }); + + startPassiveCheck(); } public checkOnline(): Promise {