import type * as d from '../declarations' ; import type { Server } from 'http' ; import * as ws from 'ws' ; import { noop } from '@utils' ; export function createWebSocket ( httpServer , onMessageFromClient ) { const wsConfig = { server : httpServer , } ; const wsServer = new ws . Server ( wsConfig ) ; function heartbeat ( this ) { this . isAlive = true ; } wsServer . on ( 'connection' , ( ws ) => { ws . on ( 'message' , ( data ) => { try { onMessageFromClient ( JSON . parse ( data . toString ( ) ) ) ; } catch ( e ) { console . error ( e ) ; } } ) ; ws . isAlive = true ; ws . on ( 'pong' , heartbeat ) ; ws . on ( 'error' , console . error ) ; } ) ; const pingInternval = setInterval ( ( ) => { wsServer . clients . forEach ( ( ws ) => { if ( ! ws . isAlive ) { return ws . close ( 1000 ) ; } ws . isAlive = false ; ws . ping ( noop ) ; } ) ; } , 10000 ) ; return { sendToBrowser : ( msg ) => { if ( msg && wsServer && wsServer . clients ) { const data = JSON . stringify ( msg ) ; wsServer . clients . forEach ( ( ws ) => { if ( ws . readyState === ws . OPEN ) { ws . send ( data ) ; } } ) ; } } , close : ( ) => { return new Promise ( ( resolve , reject ) => { clearInterval ( pingInternval ) ; wsServer . clients . forEach ( ( ws ) => { ws . close ( 1000 ) ; } ) ; wsServer . close ( ( err ) => { if ( err ) { reject ( err ) ; } else { resolve ( ) ; } } ) ; } ) ; } , } ; } export interface DevWebSocket { sendToBrowser : ( msg : d . DevServerMessage ) => void ; close : ( ) => Promise < void > ; } interface DevWS extends ws { isAlive : boolean ; }