| 10 | import { BaseServiceType } from 'tsrpc-proto'; |
| 11 | |
| 12 | export class WsServer<ServiceType extends BaseServiceType = any, SessionType = { [key: string]: any | undefined }> extends BaseServer<WsServerOptions<ServiceType, SessionType>, ServiceType> { |
| 13 | |
| 14 | protected _poolApiCall: Pool<ApiCallWs> = new Pool<ApiCallWs>(ApiCallWs); |
| 15 | protected _poolMsgCall: Pool<MsgCallWs> = new Pool<MsgCallWs>(MsgCallWs); |
| 16 | |
| 17 | private readonly _conns: WsConnection<ServiceType, SessionType>[] = []; |
| 18 | private readonly _id2Conn: { [connId: string]: WsConnection<ServiceType, SessionType> | undefined } = {}; |
| 19 | |
| 20 | private _connIdCounter = new Counter(1); |
| 21 | |
| 22 | get dataFlow(): ((data: Buffer, conn: WsConnection<ServiceType, SessionType>) => (boolean | Promise<boolean>))[] { |
| 23 | return this._dataFlow; |
| 24 | }; |
| 25 | |
| 26 | constructor(options?: Partial<WsServerOptions<ServiceType, SessionType>>) { |
| 27 | super(Object.assign({}, defaultWsServerOptions, options)); |
| 28 | } |
| 29 | |
| 30 | private _status: WsServerStatus = 'closed'; |
| 31 | public get status(): WsServerStatus { |
| 32 | return this._status; |
| 33 | } |
| 34 | |
| 35 | private _wsServer?: WebSocketServer; |
| 36 | start(): Promise<void> { |
| 37 | if (this._wsServer) { |
| 38 | throw new Error('Server already started'); |
| 39 | } |
| 40 | |
| 41 | this._status = 'opening'; |
| 42 | return new Promise(rs => { |
| 43 | this.logger.log('Starting WebSocket server...'); |
| 44 | this._wsServer = new WebSocketServer({ |
| 45 | port: this.options.port |
| 46 | }, () => { |
| 47 | this.logger.log(`Server started at ${this.options.port}...`); |
| 48 | this._status = 'open'; |
| 49 | rs(); |
| 50 | }); |
| 51 | |
| 52 | this._wsServer.on('connection', this._onClientConnect); |
| 53 | this._wsServer.on('error', e => { |
| 54 | this.logger.error('[Server Error]', e); |
| 55 | }); |
| 56 | }) |
| 57 | } |
| 58 | |
| 59 | private _stopping?: { |
| 60 | rs: () => void, |
| 61 | rj: (e: any) => void; |
| 62 | } |
| 63 | async stop(immediately: boolean = false): Promise<void> { |
| 64 | if (!this._wsServer || this._status === 'closed') { |
| 65 | return; |
| 66 | } |
| 67 | |
| 68 | this._status = 'closing'; |
| 69 | let output = new Promise<void>(async (rs, rj) => { |
nothing calls this directly
no test coverage detected