import * as events from 'events' ; import { inject , injectable } from 'inversify' ; import * as apid from '../../../api' ; import { OperatorFinishEncodeInfo } from '../event/IOperatorEncodeEvent' ; import ILogger from '../ILogger' ; import ILoggerModel from '../ILoggerModel' ; import { AddVideoFileOption , UploadedVideoFileOption } from '../operator/recorded/IRecordedManageModel' ; import IEncodeManageModel from '../service/encode/IEncodeManageModel' ; import ISocketIOManageModel from '../service/socketio/ISocketIOManageModel' ; import IIPCClient , { IPCOperatorEncodeEvent , IPCRecordedManageModel , IPCRecordedTagManageModel , IPCRecordingManageModel , IPCReservationManageModel , IPCRuleManageModel , IPCThumbnailManageModel , } from './IIPCClient' ; import { ClientMessageOption , OperatorEncodeEventFunctions , ModelName , ParentMessage , PushEncodeMessage , RecordedFunctions , RecordedTagFunctions , RecordingFunctions , ReplayMessage , ReserveationFunctions , RuleFuntions , SendMessage , ThumbnailFunctions , } from './IPCMessageDefine' ; @ injectable ( ) export default class IPCClient implements IIPCClient { private socketIO : ISocketIOManageModel ; private encodeManage : IEncodeManageModel ; public reserveation ! : IPCReservationManageModel ; public recorded ! : IPCRecordedManageModel ; public recordedTag ! : IPCRecordedTagManageModel ; public recording ! : IPCRecordingManageModel ; public rule ! : IPCRuleManageModel ; public thumbnail ! : IPCThumbnailManageModel ; public encodeEvent ! : IPCOperatorEncodeEvent ; private log : ILogger ; private listener : events . EventEmitter = new events . EventEmitter ( ) ; constructor ( @ inject ( 'ILoggerModel' ) logger , @ inject ( 'ISocketIOManageModel' ) socketIO , @ inject ( 'IEncodeManageModel' ) encodeManage ) { this . log = logger . getLogger ( ) ; this . socketIO = socketIO ; this . encodeManage = encodeManage ; if ( typeof process . send === 'undefined' ) { this . log . system . fatal ( 'bit child process' ) ; } this . ipcInit ( ) ; this . setReserveation ( ) ; this . setRecorded ( ) ; this . setRecordedTag ( ) ; this . setRecording ( ) ; this . setRule ( ) ; this . setThumbnail ( ) ; this . setEncodeEvent ( ) ; } /**
     * IPC 通信初期設定
     */ private ipcInit ( ) { process . on ( 'message' , async ( msg ) => { if ( typeof ( < ReplayMessage > msg ) . id !== 'undefined' ) { this . listener . emit ( ( < ReplayMessage > msg ) . id . toString ( 10 ) , msg ) ; } else if ( ( < ParentMessage > msg ) . type === 'notifyClient' ) { this . socketIO . notifyClient ( ) ; } else if ( ( < ParentMessage > msg ) . type === 'pushEncode' ) { this . encodeManage . push ( ( < PushEncodeMessage > msg ) . value ) ; } } ) ; } param option return private send < T > ( option , timeout = 5000 ) { const msg = { id : new Date ( ) . getTime ( ) , model : option . model , func : option . func , args : option . args , } ; process . nextTick ( ( ) => { if ( typeof process . send === 'undefined' ) { this . log . system . error ( 'process.send is undefined' ) ; return ; } process . send ( msg ) ; } ) ; return new Promise < T > ( ( resolve , reject ) => { this . listener . once ( msg . id . toString ( 10 ) , ( replay ) => { if ( typeof replay . error === 'undefined' ) { resolve ( < T > replay . result ) ; } else { reject ( new Error ( replay . error ) ) ; } } ) ; if ( timeout > 0 ) { setTimeout ( ( ) => { this . listener . removeAllListeners ( msg . id . toString ( 10 ) ) ; reject ( new Error ( 'IPCTimeout' ) ) ; } , timeout ) ; } } ) ; } /**
     * set reserveation
     */ private setReserveation ( ) { this . reserveation = { getBroadcastStatus : ( ) => { return this . send < apid . BroadcastStatus > ( { model : ModelName . reserveation , func : ReserveationFunctions . getBroadcastStatus , } ) ; } , add : ( option ) => { return this . send < apid . ReserveId > ( { model : ModelName . reserveation , func : ReserveationFunctions . add , args : { option : option , } , } ) ; } , update : ( reserveId ) => { return this . send ( { model : ModelName . reserveation , func : ReserveationFunctions . update , args : { reserveId : reserveId , } , } ) ; } , updateRule : ( ruleId ) => { return this . send ( { model : ModelName . reserveation , func : ReserveationFunctions . updateRule , args : { ruleId : ruleId , } , } ) ; } , updateAll : ( isUntilComplete ) => { return this . send ( { model : ModelName . reserveation , func : ReserveationFunctions . updateAll , args : { isUntilComplete : isUntilComplete , } , } ) ; } , cancel : ( reserveId ) => { return this . send ( { model : ModelName . reserveation , func : ReserveationFunctions . cancel , args : { reserveId : reserveId , } , } ) ; } , removeSkip : ( reserveId ) => { return this . send ( { model : ModelName . reserveation , func : ReserveationFunctions . removeSkip , args : { reserveId : reserveId , } , } ) ; } , removeOverlap : ( reserveId ) => { return this . send ( { model : ModelName . reserveation , func : ReserveationFunctions . removeOverlap , args : { reserveId : reserveId , } , } ) ; } , edit : ( reserveId , option ) => { return this . send ( { model : ModelName . reserveation , func : ReserveationFunctions . edit , args : { reserveId : reserveId , option : option , } , } ) ; } , clean : ( ) => { return this . send ( { model : ModelName . reserveation , func : ReserveationFunctions . clean , } ) ; } , } ; } /**
     * set recorded
     */ private setRecorded ( ) { this . recorded = { delete : ( recordedId ) => { this . log . system . info ( `delete recorded by ipc: ${ recordedId }` ) ; return this . send ( { model : ModelName . recorded , func : RecordedFunctions . delete , args : { recordedId : recordedId , } , } ) ; } , updateVideoFileSize : ( videoFileId ) => { return this . send ( { model : ModelName . recorded , func : RecordedFunctions . updateVideoFileSize , args : { videoFileId : videoFileId , } , } ) ; } , addVideoFile : ( option ) => { return this . send < apid . VideoFileId > ( { model : ModelName . recorded , func : RecordedFunctions . addVideoFile , args : { option : option , } , } ) ; } , addUploadedVideoFile : ( option ) => { return this . send ( { model : ModelName . recorded , func : RecordedFunctions . addUploadedVideoFile , args : { option : option , } , } , 10 * 60 * 1000 ) ; } , createNewRecorded : ( option , isIgnoreProtection ? ) => { return this . send < apid . RecordedId > ( { model : ModelName . recorded , func : RecordedFunctions . createNewRecorded , args : { option : option , isIgnoreProtection : isIgnoreProtection , } , } ) ; } , deleteVideoFile : ( videoFileId ) => { return this . send ( { model : ModelName . recorded , func : RecordedFunctions . deleteVideoFile , args : { videoFileId : videoFileId , } , } ) ; } , changeProtect : ( recordedId , isProtect ) => { return this . send ( { model : ModelName . recorded , func : RecordedFunctions . changeProtect , args : { recordedId : recordedId , isProtect : isProtect , } , } ) ; } , videoFileCleanup : ( ) => { return this . send ( { model : ModelName . recorded , func : RecordedFunctions . videoFileCleanup , } , 0 ) ; } , dropLogFileCleanup : ( ) => { return this . send ( { model : ModelName . recorded , func : RecordedFunctions . dropLogFileCleanup , } , 0 ) ; } , } ; } /**
     * set recordedTag
     */ private setRecordedTag ( ) { this . recordedTag = { create : ( name , color ) => { return this . send ( { model : ModelName . recordedTag , func : RecordedTagFunctions . create , args : { name : name , color : color , } , } ) ; } , update : ( tagId , name , color ) => { return this . send ( { model : ModelName . recordedTag , func : RecordedTagFunctions . update , args : { tagId : tagId , name : name , color : color , } , } ) ; } , setRelation : ( tagId , recordedId ) => { return this . send ( { model : ModelName . recordedTag , func : RecordedTagFunctions . setRelation , args : { tagId : tagId , recordedId : recordedId , } , } ) ; } , delete : ( tagId ) => { return this . send ( { model : ModelName . recordedTag , func : RecordedTagFunctions . delete , args : { tagId : tagId , } , } ) ; } , deleteRelation : ( tagId , recordedId ) => { return this . send ( { model : ModelName . recordedTag , func : RecordedTagFunctions . deleteRelation , args : { tagId : tagId , recordedId : recordedId , } , } ) ; } , } ; } /**
     * set recording
     */ private setRecording ( ) { this . recording = { resetTimer : ( ) => { return this . send ( { model : ModelName . recording , func : RecordingFunctions . resetTimer , } ) ; } , } ; } /**
     * set rule
     */ private setRule ( ) { this . rule = { add : ( rule ) => { return this . send ( { model : ModelName . rule , func : RuleFuntions . add , args : { rule : rule , } , } ) ; } , update : ( rule ) => { return this . send ( { model : ModelName . rule , func : RuleFuntions . update , args : { rule : rule , } , } ) ; } , enable : ( ruleId ) => { return this . send ( { model : ModelName . rule , func : RuleFuntions . enable , args : { ruleId : ruleId , } , } ) ; } , disable : ( ruleId ) => { return this . send ( { model : ModelName . rule , func : RuleFuntions . disable , args : { ruleId : ruleId , } , } ) ; } , delete : ( ruleId ) => { return this . send ( { model : ModelName . rule , func : RuleFuntions . delete , args : { ruleId : ruleId , } , } ) ; } , deletes : ( ruleIds ) => { return this . send ( { model : ModelName . rule , func : RuleFuntions . deletes , args : { ruleIds : ruleIds , } , } ) ; } , } ; } /**
     * set thumbnail
     */ private setThumbnail ( ) { this . thumbnail = { regenerate : ( ) => { return this . send ( { model : ModelName . thumbnail , func : ThumbnailFunctions . regenerate , } ) ; } , fileCleanup : ( ) => { return this . send ( { model : ModelName . thumbnail , func : ThumbnailFunctions . fileCleanup , } ) ; } , add : videoFileId => { return this . send ( { model : ModelName . thumbnail , func : ThumbnailFunctions . add , args : { videoFileId : videoFileId , } , } ) ; } , delete : thumbnailId => { return this . send ( { model : ModelName . thumbnail , func : ThumbnailFunctions . delete , args : { thumbnailId : thumbnailId , } , } ) ; } , } ; } /**
     * set encode event
     */ private setEncodeEvent ( ) { this . encodeEvent = { emitFinishEncode : ( info ) => { return this . send ( { model : ModelName . encodeEvent , func : OperatorEncodeEventFunctions . emitFinishEncode , args : { info : info , } , } ) ; } , } ; } }