From f0e108f87b8ffb533afde460d049c420af876143 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Wed, 30 Jun 2021 17:01:27 -0600 Subject: [PATCH] better connection service --- ui/src/app/app.component.ts | 12 +-- ui/src/app/models/patch-db/patch-db-model.ts | 5 +- ui/src/app/services/connection.service.ts | 81 +++++++------------- 3 files changed, 35 insertions(+), 63 deletions(-) diff --git a/ui/src/app/app.component.ts b/ui/src/app/app.component.ts index 568843242..192e37282 100644 --- a/ui/src/app/app.component.ts +++ b/ui/src/app/app.component.ts @@ -3,7 +3,7 @@ import { Storage } from '@ionic/storage' import { AuthService, AuthState } from './services/auth.service' import { ApiService } from './services/api/api.service' import { Router, RoutesRecognized } from '@angular/router' -import { distinctUntilChanged, filter, finalize, map, takeWhile } from 'rxjs/operators' +import { distinctUntilChanged, filter, finalize, takeWhile } from 'rxjs/operators' import { AlertController, ToastController } from '@ionic/angular' import { LoaderService } from './services/loader.service' import { Emver } from './services/emver.service' @@ -84,7 +84,7 @@ export class AppComponent { this.showMenu = true this.patch.start() // watch network - this.watchNetwork(auth) + this.watchConnection(auth) // watch router to highlight selected menu item this.watchRouter(auth) // watch status to display/hide maintenance page @@ -106,14 +106,14 @@ export class AppComponent { }) } - private watchNetwork (auth: AuthState): void { + private watchConnection (auth: AuthState): void { this.connectionService.monitor$() .pipe( distinctUntilChanged(), takeWhile(() => auth === AuthState.VERIFIED), ) - .subscribe(c => { - if (!c.network || !c.internet) { + .subscribe(internet => { + if (!internet) { this.presentToastOffline() } else { if (this.offlineToast) { @@ -121,7 +121,7 @@ export class AppComponent { this.offlineToast = undefined } } - console.log('CONNECTION CHANGED', c) + console.log('INTERNET CONNECTION', internet) }) } diff --git a/ui/src/app/models/patch-db/patch-db-model.ts b/ui/src/app/models/patch-db/patch-db-model.ts index 317010661..dfcbb62f8 100644 --- a/ui/src/app/models/patch-db/patch-db-model.ts +++ b/ui/src/app/models/patch-db/patch-db-model.ts @@ -36,11 +36,10 @@ export class PatchDbModel { this.bootstrapper.update(cache) }, error: e => { - console.error('Critical, patch-db-sync sub error', e) - this.start() + console.error('patch-db-sync sub ERROR', e) }, complete: () => { - console.error('Critical, patch-db-sync sub complete') + console.error('patch-db-sync sub COMPLETE') }, }) } catch (e) { diff --git a/ui/src/app/services/connection.service.ts b/ui/src/app/services/connection.service.ts index 08359f141..a5394aa32 100644 --- a/ui/src/app/services/connection.service.ts +++ b/ui/src/app/services/connection.service.ts @@ -1,69 +1,41 @@ import { Injectable } from '@angular/core' -import { fromEvent, Observable, Subject, Subscription, timer } from 'rxjs' -import { debounceTime, delay, retryWhen, startWith, switchMap, tap } from 'rxjs/operators' +import { BehaviorSubject, fromEvent, merge, Observable, Subscription, timer } from 'rxjs' +import { delay, retryWhen, switchMap, tap } from 'rxjs/operators' import { ApiService } from './api/api.service' @Injectable({ providedIn: 'root', }) export class ConnectionService { - private offlineSubscription$: Subscription - private onlineSubscription$: Subscription private httpSubscription$: Subscription - private readonly currentState: ConnectionState = { - network: true, - internet: true, - } - private readonly stateChangeEventEmitter = new Subject() + private readonly networkState$ = new BehaviorSubject(navigator.onLine) + private readonly internetState$ = new BehaviorSubject(null) constructor ( private readonly apiService: ApiService, ) { - this.checkNetworkState() - this.checkInternetState() - } - - ngOnDestroy (): void { - try { - this.offlineSubscription$.unsubscribe() - this.onlineSubscription$.unsubscribe() - this.httpSubscription$.unsubscribe() - } catch (e) { - console.error(e.message) - } - } - - /** - * Monitor Network & Internet connection status by subscribing to this observer. - */ - monitor$ (): Observable { - return this.stateChangeEventEmitter.pipe( - debounceTime(300), - startWith(this.currentState), - ) - } - - private checkNetworkState (): void { - this.onlineSubscription$ = fromEvent(window, 'online').subscribe(() => { - this.currentState.network = true - this.checkInternetState() - this.emitEvent() + merge(fromEvent(window, 'online'), fromEvent(window, 'offline')) + .subscribe(event => { + this.networkState$.next(event.type === 'online') }) - this.offlineSubscription$ = fromEvent(window, 'offline').subscribe(() => { - this.currentState.network = false - if (this.httpSubscription$) { - this.httpSubscription$.unsubscribe() + this.networkState$ + .subscribe(online => { + if (online) { + this.testInternet() + } else { + this.killHttp() + this.internetState$.next(false) } - this.emitEvent() }) } - private checkInternetState (): void { + monitor$ (): Observable { + return this.internetState$.asObservable() + } - if (this.httpSubscription$) { - this.httpSubscription$.unsubscribe() - } + private testInternet (): void { + this.killHttp() // ping server every 10 seconds this.httpSubscription$ = timer(0, 10000) @@ -73,8 +45,7 @@ export class ConnectionService { errors.pipe( tap(val => { console.error('Echo error: ', val) - this.currentState.internet = false - this.emitEvent() + this.internetState$.next(false) }), // restart after 2 seconds delay(2000), @@ -82,13 +53,15 @@ export class ConnectionService { ), ) .subscribe(() => { - this.currentState.internet = true - this.emitEvent() + this.internetState$.next(true) }) } - private emitEvent (): void { - this.stateChangeEventEmitter.next({ ...this.currentState }) + private killHttp () { + if (this.httpSubscription$) { + this.httpSubscription$.unsubscribe() + this.httpSubscription$ = undefined + } } } @@ -103,5 +76,5 @@ export class ConnectionService { /** * "True" if browser has Internet access. Determined by heartbeat system which periodically makes request to heartbeat Url. */ - internet: boolean + internet: boolean | null } \ No newline at end of file