import { SocketHandler , SocketMessage } from "../core/socket-handler" ; import { Global } from "../core/global" ; const KeepAlivePeriod = 30000 ; const KeepAliveWindowPeriod = 300000 ; const KeepAliveWarningThreshold = 5 ; /**
 * Handles keeping the client connection alive.
 * I resisted the urge to call this "Stayin' Alive" - you're welcome!
 */ export class KeepAlive { public pingPeriod : number = KeepAlivePeriod ; public windowPeriod : number = KeepAliveWindowPeriod ; public warningThreshold : number = KeepAliveWarningThreshold ; private keepAliveArray : Array < number > = [ ] ; private startedTimestamp : number ; private onFailureCallback : ( ) => void ; private timeout : any = null ; private stopped : boolean = false ; public constructor ( private socket ) { } /**
     * Pings the server on a 5-second period to keep the connection alive
     */ public start ( onFailureCallback ) { this . onFailureCallback = onFailureCallback ; this . reset ( ) ; this . keepAlive ( ) ; } public reset ( ) { this . startedTimestamp = new Date ( ) . getTime ( ) ; } private keepAlive ( ) { let self = this ; if ( ( new Date ( ) . getTime ( ) - this . startedTimestamp ) > this . windowPeriod ) { this . keepAliveArray = this . keepAlivesInPeriod ( this . windowPeriod ) ; if ( this . keepAliveArray . length <= this . warningThreshold ) { this . onFailureCallback ( ) ; this . reset ( ) ; } } this . timeout = setTimeout ( function ( ) { if ( ! self . stopped ) { self . socket . send ( new SocketMessage ( Global . KeepAliveMessage ) ) ; self . keepAlive ( ) ; } } , this . pingPeriod ) ; } private keepAlivesInPeriod ( periodInMilliseconds ) { let newArray = [ ] ; let rightNow = new Date ( ) . getTime ( ) ; for ( let timestamp of this . keepAliveArray ) { let secondsPassed = rightNow - timestamp ; if ( secondsPassed < periodInMilliseconds ) { newArray . push ( timestamp ) ; } } return newArray ; } public received ( ) { this . keepAliveArray . push ( new Date ( ) . getTime ( ) ) ; } public stop ( ) { if ( this . timeout !== null ) { this . stopped = true ; clearTimeout ( this . timeout ) ; } } }