better connection service

This commit is contained in:
Matt Hill
2021-06-30 17:01:27 -06:00
committed by Aiden McClelland
parent a2103d4307
commit f0e108f87b
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 { 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)
})
}

View File

@@ -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) {

View File

@@ -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<ConnectionState>()
private readonly networkState$ = new BehaviorSubject<boolean>(navigator.onLine)
private readonly internetState$ = new BehaviorSubject<boolean | null>(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<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()
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<boolean> {
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
}