@mean-expert/loopback-sdk-builder
Version:
Tool for auto-generating Software Development Kits (SDKs) for LoopBack
114 lines (113 loc) • 4.34 kB
text/typescript
import { Injectable, Inject } from '@angular/core';
import { IO } from './io.service';
import { LoopBackAuth } from './auth.service';
import { FireLoop } from '../../models/FireLoop';
import { SocketConnection } from '../../sockets/socket.connections';
import { SDKModels } from '../custom/SDKModels';
import { Observable, Subject, Subscription } from 'rxjs';
import { share } from 'rxjs/operators';
/**
* @author Jonathan Casarrubias <twitter:@johncasarrubias> <github:@johncasarrubias>
* @module RealTime
* @license MIT
* @description
* This module is a real-time interface for using socket connections, its main purpose
* is to make sure that when there is a valid connection, it will create instances
* of the different real-time functionalities like FireLoop, PubSub and IO.
**/
export class RealTime {
public IO: IO;
public FireLoop: FireLoop;
private connecting: boolean = false;
private onReadySubject: Subject<string> = new Subject<string>();
private sharedOnReady: Observable<string> = this.onReadySubject.asObservable().pipe(share());
/**
* @method constructor
* @param {SocketConnection} connection WebSocket connection service
* @param {SDKModels} models Model provider service
* @param {LoopBackAuth} auth LoopBack authentication service
* @description
* It will intialize the shared on ready communication channel.
**/
constructor(
public connection: SocketConnection,
protected models: SDKModels,
protected auth: LoopBackAuth
) {
this.sharedOnReady.subscribe();
}
/**
* @method onDisconnect
* @return {Observable<any>}
* @description
* Will trigger when Real-Time Service is disconnected from server.
**/
onDisconnect(): Observable<any> {
return this.connection.sharedObservables.sharedOnDisconnect;
}
/**
* @method onAuthenticated
* @return {Observable<any>}
* @description
* Will trigger when Real-Time Service is authenticated with the server.
**/
onAuthenticated(): Observable<any> {
return this.connection.sharedObservables.sharedOnAuthenticated;
}
/**
* @method onUnAuthorized
* @return {Observable<any>}
* @description
* Will trigger when Real-Time Service is not authorized to connect with the server.
**/
onUnAuthorized(): Observable<any> {
return this.connection.sharedObservables.sharedOnUnAuthorized;
}
/**
* @method onReady
* @return {Observable<any>}
* @description
* Will trigger when Real-Time Service is Ready for broadcasting.
* and will register connection flow events to notify subscribers.
**/
public onReady(): Observable<any> {
// If there is a valid connection, then we just send back to the EventLoop
// Or next will be executed before the actual subscription.
if (this.connection.isConnected()) {
let to = setTimeout(() => {
this.onReadySubject.next('shared-connection');
clearTimeout(to);
});
// Else if there is a current attempt of connection we wait for the prior
// process that started the connection flow.
} else if (this.connecting) {
let ti = setInterval(() => {
if (this.connection.isConnected()) {
this.onReadySubject.next('shared-connection');
clearInterval(ti);
}
}, 500);
// If there is not valid connection or attempt, then we start the connection flow
// and make sure we notify all the onReady subscribers when done.
// Also it will listen for desconnections so we unsubscribe and avoid both:
// Memory leaks and duplicated triggered events.
} else {
this.connecting = true;
this.connection.connect(this.auth.getToken());
this.IO = new IO(this.connection);
this.FireLoop = new FireLoop(this.connection, this.models);
// Fire event for those subscribed
let s1: Subscription = this.connection.sharedObservables.sharedOnConnect.subscribe(() => {
console.log('Real-Time connection has been established');
this.connecting = false;
this.onReadySubject.next('connected');
let s2: Subscription = this.connection.sharedObservables.sharedOnDisconnect.subscribe(() => {
s1.unsubscribe();
s2.unsubscribe();
});
});
}
return this.sharedOnReady;
}
}