import { ServiceStore } from './store' ; import { CallStore } from './call_store' ; import { IGBServerMessage , IGBClientMessage , IGBSendCall , IGBCreateService , IGBCreateServiceResult , IGBReleaseService , IGBCreateCall , IGBEndCall , } from '../proto' ; export class Server { private store : ServiceStore ; private clientIdToService : { [ id ] : CallStore ; } = { } ; public constructor ( private protoTree , private send , private grpc ) { this . store = new ServiceStore ( protoTree , this . grpc ) ; } public handleMessage ( message ) { if ( message . service_create ) { this . handleServiceCreate ( message . service_create ) ; } if ( message . service_release ) { this . handleServiceRelease ( message . service_release ) ; } if ( message . call_create ) { this . handleCallCreate ( message . call_create ) ; } if ( message . call_end ) { this . handleCallEnd ( message . call_end ) ; } if ( message . call_send ) { this . handleCallSend ( message . call_send ) ; } } public dispose ( ) { for ( let servId in this . clientIdToService ) { if ( ! this . clientIdToService . hasOwnProperty ( servId ) ) { continue ; } this . clientIdToService [ servId ] . dispose ( ) ; } this . clientIdToService = { } ; } private releaseLocalService ( serviceId , sendGratuitous = true ) { let srv = this . clientIdToService [ serviceId ] ; if ( srv ) { sendGratuitous = true ; delete this . clientIdToService [ serviceId ] ; srv . dispose ( ) ; } if ( sendGratuitous ) { this . send ( { service_release : { service_id : serviceId , } , } ) ; } } private handleServiceCreate ( msg ) { let serviceId = msg . service_id ; let result = { service_id : msg . service_id , result : 0 , } ; if ( typeof msg . service_id !== 'number' || this . clientIdToService [ msg . service_id ] ) { result . result = 1 ; result . error_details = 'ID is not set or is already in use.' ; } else { try { let serv = this . store . getService ( msg . service_id , msg . service_info ) ; serv . initStub ( ) ; serv . disposed . subscribe ( ( ) => { this . releaseLocalService ( serviceId , false ) ; } ) ; this . clientIdToService [ serviceId ] = new CallStore ( serv , msg . service_id , this . send ) ; } catch ( e ) { result . result = 2 ; result . error_details = e . toString ( ) ; } } this . send ( { service_create : result , } ) ; } private handleServiceRelease ( msg ) { this . releaseLocalService ( msg . service_id ) ; } private handleCallSend ( msg ) { let svc = this . clientIdToService [ msg . service_id ] ; if ( ! svc ) { this . releaseLocalService ( msg . service_id , true ) ; return ; } svc . handleCallWrite ( msg ) ; } private handleCallCreate ( msg ) { let svc = this . clientIdToService [ msg . service_id ] ; if ( ! svc ) { this . send ( { call_create : { result : 1 , service_id : msg . service_id , call_id : msg . call_id , error_details : 'Service ID not found.' , } , } ) ; return ; } svc . initCall ( msg ) ; } private handleCallEnd ( msg ) { let svc = this . clientIdToService [ msg . service_id ] ; if ( svc ) { svc . handleCallEnd ( msg ) ; } } }