better connection service

This commit is contained in:
Matt Hill
2021-06-30 17:01:27 -06:00
committed by Aiden McClelland
parent 8cb4351668
commit 80db9b71b9
3 changed files with 35 additions and 63 deletions

View File

@@ -3,7 +3,7 @@ import { Storage } from '@ionic/storage'
import { AuthService, AuthState } from './services/auth.service' import { AuthService, AuthState } from './services/auth.service'
import { ApiService } from './services/api/api.service' import { ApiService } from './services/api/api.service'
import { Router, RoutesRecognized } from '@angular/router' 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 { AlertController, ToastController } from '@ionic/angular'
import { LoaderService } from './services/loader.service' import { LoaderService } from './services/loader.service'
import { Emver } from './services/emver.service' import { Emver } from './services/emver.service'
@@ -84,7 +84,7 @@ export class AppComponent {
this.showMenu = true this.showMenu = true
this.patch.start() this.patch.start()
// watch network // watch network
this.watchNetwork(auth) this.watchConnection(auth)
// watch router to highlight selected menu item // watch router to highlight selected menu item
this.watchRouter(auth) this.watchRouter(auth)
// watch status to display/hide maintenance page // 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$() this.connectionService.monitor$()
.pipe( .pipe(
distinctUntilChanged(), distinctUntilChanged(),
takeWhile(() => auth === AuthState.VERIFIED), takeWhile(() => auth === AuthState.VERIFIED),
) )
.subscribe(c => { .subscribe(internet => {
if (!c.network || !c.internet) { if (!internet) {
this.presentToastOffline() this.presentToastOffline()
} else { } else {
if (this.offlineToast) { if (this.offlineToast) {
@@ -121,7 +121,7 @@ export class AppComponent {
this.offlineToast = undefined this.offlineToast = undefined
} }
} }
console.log('CONNECTION CHANGED', c) console.log('INTERNET CONNECTION', internet)
}) })
} }

View File

@@ -36,11 +36,10 @@ export class PatchDbModel {
this.bootstrapper.update(cache) this.bootstrapper.update(cache)
}, },
error: e => { error: e => {
console.error('Critical, patch-db-sync sub error', e) console.error('patch-db-sync sub ERROR', e)
this.start()
}, },
complete: () => { complete: () => {
console.error('Critical, patch-db-sync sub complete') console.error('patch-db-sync sub COMPLETE')
}, },
}) })
} catch (e) { } catch (e) {

View File

@@ -1,69 +1,41 @@
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { fromEvent, Observable, Subject, Subscription, timer } from 'rxjs' import { BehaviorSubject, fromEvent, merge, Observable, Subscription, timer } from 'rxjs'
import { debounceTime, delay, retryWhen, startWith, switchMap, tap } from 'rxjs/operators' import { delay, retryWhen, switchMap, tap } from 'rxjs/operators'
import { ApiService } from './api/api.service' import { ApiService } from './api/api.service'
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class ConnectionService { export class ConnectionService {
private offlineSubscription$: Subscription
private onlineSubscription$: Subscription
private httpSubscription$: Subscription private httpSubscription$: Subscription
private readonly currentState: ConnectionState = { private readonly networkState$ = new BehaviorSubject<boolean>(navigator.onLine)
network: true, private readonly internetState$ = new BehaviorSubject<boolean | null>(null)
internet: true,
}
private readonly stateChangeEventEmitter = new Subject<ConnectionState>()
constructor ( constructor (
private readonly apiService: ApiService, private readonly apiService: ApiService,
) { ) {
this.checkNetworkState() merge(fromEvent(window, 'online'), fromEvent(window, 'offline'))
this.checkInternetState() .subscribe(event => {
} this.networkState$.next(event.type === 'online')
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<ConnectionState> {
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()
}) })
this.offlineSubscription$ = fromEvent(window, 'offline').subscribe(() => { this.networkState$
this.currentState.network = false .subscribe(online => {
if (this.httpSubscription$) { if (online) {
this.httpSubscription$.unsubscribe() this.testInternet()
} else {
this.killHttp()
this.internetState$.next(false)
} }
this.emitEvent()
}) })
} }
private checkInternetState (): void { monitor$ (): Observable<boolean> {
return this.internetState$.asObservable()
}
if (this.httpSubscription$) { private testInternet (): void {
this.httpSubscription$.unsubscribe() this.killHttp()
}
// ping server every 10 seconds // ping server every 10 seconds
this.httpSubscription$ = timer(0, 10000) this.httpSubscription$ = timer(0, 10000)
@@ -73,8 +45,7 @@ export class ConnectionService {
errors.pipe( errors.pipe(
tap(val => { tap(val => {
console.error('Echo error: ', val) console.error('Echo error: ', val)
this.currentState.internet = false this.internetState$.next(false)
this.emitEvent()
}), }),
// restart after 2 seconds // restart after 2 seconds
delay(2000), delay(2000),
@@ -82,13 +53,15 @@ export class ConnectionService {
), ),
) )
.subscribe(() => { .subscribe(() => {
this.currentState.internet = true this.internetState$.next(true)
this.emitEvent()
}) })
} }
private emitEvent (): void { private killHttp () {
this.stateChangeEventEmitter.next({ ...this.currentState }) 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. * "True" if browser has Internet access. Determined by heartbeat system which periodically makes request to heartbeat Url.
*/ */
internet: boolean internet: boolean | null
} }