UNPKG

abstruse

Version:
65 lines (57 loc) 2.02 kB
import { Injectable, Provider, EventEmitter } from '@angular/core'; import { RxWebSocket, ConnectionStates } from '../classes/rx-web-socket.class'; import { Observable, Subscriber, BehaviorSubject, timer, fromEvent } from 'rxjs'; import { share, retryWhen, switchMap, take } from 'rxjs/operators'; @Injectable() export class SocketService { connectionState: BehaviorSubject<ConnectionStates>; socket: RxWebSocket; outputEvents: EventEmitter<any>; timeSyncDiff: number; constructor() { this.socket = new RxWebSocket(); this.connectionState = new BehaviorSubject<ConnectionStates>(ConnectionStates.CONNECTING); this.socket.didOpen = () => this.connectionState.next(ConnectionStates.CONNECTED); this.socket.willOpen = () => this.connectionState.next(ConnectionStates.CONNECTING); this.socket.didClose = () => this.connectionState.next(ConnectionStates.CLOSED); this.outputEvents = new EventEmitter<any>(); this.onMessage().subscribe(event => { if (event.type === 'time') { this.timeSyncDiff = new Date().getTime() - event.data; } else { this.outputEvents.emit(event); } }); } connect(): Observable<any> { return new Observable((subscriber: Subscriber<any>) => { const sub = this.socket.out.subscribe(subscriber); return () => { sub.unsubscribe(); }; }) .pipe( share(), retryWhen(errors => { return errors.pipe(switchMap(err => { this.connectionState.next(ConnectionStates.RETRYING); if (navigator.onLine) { return timer(3000); } else { return fromEvent(window, 'online').pipe(take(1)); } })); }) ); } onMessage(): Observable<any> { return this.connect(); } emit(msg: any) { const data = typeof msg === 'string' ? msg : JSON.stringify(msg); this.socket.in.next(data); } } export const SocketServiceProvider: Provider = { provide: SocketService, useClass: SocketService };