UNPKG

rerummagni

Version:
132 lines (114 loc) 5.64 kB
import * as _ from 'lodash'; import { ClassType, DateUtil, ExtendedError, ITransportCommand, ITransportCommandAsync, ITransportCommandRequest, ITransportEvent, ITransportSettings, ObjectUtil, TransformUtil, TransportCommand, TransportCommandAsync, TransportEvent, TransportImpl, TransportLogType, ValidateUtil } from '@ts-core/common'; import { ITransportSocketEventOptions } from './ITransportSocketEventOptions'; import { TransportSocketRequestPayload } from './TransportSocketRequestPayload'; import { ITransportSocketCommandOptions } from './ITransportSocketCommandOptions'; import { ITransportSocketRequestPayload } from './ITransportSocketRequestPayload'; import { TransportSocketResponsePayload } from './TransportSocketResponsePayload'; import { ITransportSocketResponsePayload } from './ITransportSocketResponsePayload'; import { TransportSocketUserId } from './TransportSocketUserId'; export abstract class TransportSocketImpl extends TransportImpl<ITransportSettings, ITransportSocketCommandOptions, ITransportSocketCommandRequest, ITransportSocketEventOptions> { // -------------------------------------------------------------------------- // // Request Methods // // -------------------------------------------------------------------------- protected createRequestPayload<U>(command: ITransportCommand<U>, options: ITransportSocketCommandOptions, isNeedReply: boolean): ITransportSocketRequestPayload<U> { let item = new TransportSocketRequestPayload<U>(command, options); item.isNeedReply = isNeedReply; ValidateUtil.validate(item); return item; } protected requestResponseReceived = (item: any): void => { if (_.isNil(item) || _.isNil(item.id)) { this.warn(`Received nil or invalid response message`); return; } let promise = this.promises.get(item.id); if (_.isNil(promise)) { this.warn(`Unable to find command promise: probably command was already completed`); return; } let payload: TransportSocketResponsePayload = null; try { payload = TransportSocketResponsePayload.parse(item); } catch (error) { payload = TransportSocketResponsePayload.fromError(item.id, ExtendedError.create(error)); } finally { this.commandRequestResponseReceived(promise, payload.response); } } // -------------------------------------------------------------------------- // // Response Methods // // -------------------------------------------------------------------------- protected createResponsePayload<U, V>(command: ITransportCommandAsync<U, V>, request: ITransportSocketCommandRequest): ITransportSocketResponsePayload<V> { let item = new TransportSocketResponsePayload(command); ValidateUtil.validate(item); return item; } protected responseRequestReceived = <U>(item: any): void => { if (_.isNil(item) || _.isNil(item.id)) { this.warn(`Received nil or invalid request`); return; } let command: ITransportCommand<U> = null; let payload: ITransportSocketRequestPayload<U> = null; try { payload = TransportSocketRequestPayload.parse(item); command = this.createCommand(payload); } catch (error) { this.warn(`Received invalid request: ${error.message}`); return; } this.logCommand(command, TransportLogType.REQUEST_RECEIVED); let request = this.checkRequestStorage(command, payload); this.commandResponseRequestDispatch(command, payload.options, payload.isNeedReply); } protected createCommand<U>(item: ITransportSocketRequestPayload<U>): ITransportCommand<U> { let CommandType: ClassType<ITransportCommand<U>> = item.isNeedReply ? TransportCommandAsync : TransportCommand; return new CommandType(item.name, item.request, item.id); } protected checkRequestStorage<U>(command: ITransportCommand<U>, payload: ITransportSocketRequestPayload<U>): ITransportSocketCommandRequest { let item = this.requests.get(command.id); if (!_.isNil(item)) { item.waited++; return item; } item = { waited: 0, isNeedReply: payload.isNeedReply, expired: null }; item = ObjectUtil.copyProperties(payload.options, item); if (item.isNeedReply) { item.expired = DateUtil.getDate(Date.now() + this.getCommandTimeoutDelay(command, payload.options)); } this.requests.set(command.id, item); return item; } // -------------------------------------------------------------------------- // // Event Methods // // -------------------------------------------------------------------------- protected requestEventReceived = <U>(item: any): void => { if (_.isNil(item) || _.isNil(item.uid)) { this.warn(`Received nil or invalid event`); return; } let event: ITransportEvent<U> = null; try { event = this.createEvent(item) } catch (error) { this.warn(`Received invalid event: ${error.message}`); return; } this.eventRequestReceived(event); } protected createEvent<U>(item: any): ITransportEvent<U> { return TransformUtil.toClass(TransportEvent, item); } } export interface ITransportSocketCommandRequest extends ITransportCommandRequest { userId?: TransportSocketUserId; clientId?: string; }