@colyseus/uwebsockets-transport
Version:
<div align="center"> <a href="https://github.com/colyseus/colyseus"> <img src="media/logo.svg?raw=true" width="60%" height="300" /> </a> <br> <br> <a href="https://npmjs.com/package/colyseus"> <img src="https://img.shields.io/npm/dm/coly
8 lines (7 loc) • 6.36 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../src/uWebSocketClient.ts"],
"sourcesContent": ["import EventEmitter from 'events';\nimport uWebSockets from 'uWebSockets.js';\n\nimport { getMessageBytes, Protocol, type Client, type ClientPrivate, ClientState, type ISendOptions, logger, debugMessage } from '@colyseus/core';\n\nexport class uWebSocketWrapper extends EventEmitter {\n public ws: uWebSockets.WebSocket<any>;\n constructor(ws: uWebSockets.WebSocket<any>) {\n super();\n this.ws = ws;\n }\n}\n\nexport const ReadyState = {\n CONNECTING: 0,\n OPEN: 1,\n CLOSING: 2,\n CLOSED: 3,\n} as const;\nexport type ReadyState = (typeof ReadyState)[keyof typeof ReadyState];\n\nexport class uWebSocketClient implements Client, ClientPrivate {\n '~messages': any;\n\n public id: string;\n public _ref: uWebSocketWrapper;\n\n public sessionId: string;\n public state: ClientState = ClientState.JOINING;\n public readyState: number = ReadyState.OPEN;\n public reconnectionToken: string;\n\n public _enqueuedMessages: any[] = [];\n public _afterNextPatchQueue;\n public _reconnectionToken: string;\n public _joinedAt: number;\n\n constructor(id: string, _ref: uWebSocketWrapper) {\n this.id = this.sessionId = id;\n this._ref = _ref;\n _ref.on('close', () => this.readyState = ReadyState.CLOSED);\n }\n\n get ref() { return this._ref; }\n set ref(_ref: uWebSocketWrapper) {\n this._ref = _ref;\n this.readyState = ReadyState.OPEN;\n }\n\n public sendBytes(type: string | number, bytes: Buffer | Uint8Array, options?: ISendOptions) {\n debugMessage(\"send bytes(to %s): '%s' -> %j\", this.sessionId, type, bytes);\n\n this.enqueueRaw(\n getMessageBytes.raw(Protocol.ROOM_DATA_BYTES, type, undefined, bytes),\n options,\n );\n }\n\n public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) {\n debugMessage(\"send(to %s): '%s' -> %O\", this.sessionId, messageOrType, messageOrOptions);\n\n this.enqueueRaw(\n getMessageBytes.raw(Protocol.ROOM_DATA, messageOrType, messageOrOptions),\n options,\n );\n }\n\n public enqueueRaw(data: Uint8Array | Buffer, options?: ISendOptions) {\n // use room's afterNextPatch queue\n if (options?.afterNextPatch) {\n this._afterNextPatchQueue.push([this, [data]]);\n return;\n }\n\n if (this.state !== ClientState.JOINED) {\n // sending messages during `onJoin` or `onReconnect`.\n // - the client-side cannot register \"onMessage\" callbacks at this point.\n // - enqueue the messages to be send after JOIN_ROOM message has been sent\n // - create a new buffer for enqueued messages, as the underlying buffer might be modified\n this._enqueuedMessages?.push(data);\n return;\n }\n\n this.raw(data, options);\n }\n\n public raw(data: Uint8Array | Buffer, options?: ISendOptions, cb?: (err?: Error) => void) {\n // skip if client not open\n if (this.readyState !== ReadyState.OPEN) {\n return;\n }\n\n try {\n this._ref.ws.send(data, true, false);\n } catch (e: any) {\n // uWS throws \"Invalid access of closed uWS.WebSocket\" if the socket\n // closed between the readyState check and the send() call.\n this.readyState = ReadyState.CLOSED;\n }\n }\n\n public error(code: number, message: string = '', cb?: (err?: Error) => void) {\n this.raw(getMessageBytes[Protocol.ERROR](code, message));\n\n if (cb) {\n // delay callback execution - uWS doesn't acknowledge when the message was sent\n // (same API as \"ws\" transport)\n process.nextTick(cb);\n }\n }\n\n public leave(code?: number, data?: string) {\n if (this.readyState !== ReadyState.OPEN) {\n // connection already closed. ignore.\n return;\n }\n\n this.readyState = ReadyState.CLOSING;\n\n if (code !== undefined) {\n this._ref.ws.end(code, data);\n } else {\n this._ref.ws.close();\n }\n }\n\n public close(code?: number, data?: string) {\n logger.warn('DEPRECATION WARNING: use client.leave() instead of client.close()');\n try {\n throw new Error();\n } catch (e: any) {\n logger.info(e.stack);\n }\n this.leave(code, data);\n }\n\n public toJSON() {\n return { sessionId: this.sessionId, readyState: this.readyState };\n }\n}\n"],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAyB;AACzB,yBAAwB;AAExB,kBAAiI;AAE1H,IAAM,oBAAN,cAAgC,cAAAA,QAAa;AAAA,EAElD,YAAY,IAAgC;AAC1C,UAAM;AACN,SAAK,KAAK;AAAA,EACZ;AACF;AAEO,IAAM,aAAa;AAAA,EACxB,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ;AACV;AAGO,IAAM,mBAAN,MAAwD;AAAA,EAgB7D,YAAY,IAAY,MAAyB;AATjD,SAAO,QAAqB,wBAAY;AACxC,SAAO,aAAqB,WAAW;AAGvC,SAAO,oBAA2B,CAAC;AAMjC,SAAK,KAAK,KAAK,YAAY;AAC3B,SAAK,OAAO;AACZ,SAAK,GAAG,SAAS,MAAM,KAAK,aAAa,WAAW,MAAM;AAAA,EAC5D;AAAA,EAEA,IAAI,MAAM;AAAE,WAAO,KAAK;AAAA,EAAM;AAAA,EAC9B,IAAI,IAAI,MAAyB;AAC/B,SAAK,OAAO;AACZ,SAAK,aAAa,WAAW;AAAA,EAC/B;AAAA,EAEO,UAAU,MAAuB,OAA4B,SAAwB;AAC1F,kCAAa,iCAAiC,KAAK,WAAW,MAAM,KAAK;AAEzE,SAAK;AAAA,MACH,4BAAgB,IAAI,qBAAS,iBAAiB,MAAM,QAAW,KAAK;AAAA,MACpE;AAAA,IACF;AAAA,EACF;AAAA,EAEO,KAAK,eAAoB,kBAAuC,SAAwB;AAC7F,kCAAa,2BAA2B,KAAK,WAAW,eAAe,gBAAgB;AAEvF,SAAK;AAAA,MACH,4BAAgB,IAAI,qBAAS,WAAW,eAAe,gBAAgB;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AAAA,EAEO,WAAW,MAA2B,SAAwB;AAEnE,QAAI,SAAS,gBAAgB;AAC3B,WAAK,qBAAqB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC7C;AAAA,IACF;AAEA,QAAI,KAAK,UAAU,wBAAY,QAAQ;AAKrC,WAAK,mBAAmB,KAAK,IAAI;AACjC;AAAA,IACF;AAEA,SAAK,IAAI,MAAM,OAAO;AAAA,EACxB;AAAA,EAEO,IAAI,MAA2B,SAAwB,IAA4B;AAExF,QAAI,KAAK,eAAe,WAAW,MAAM;AACvC;AAAA,IACF;AAEA,QAAI;AACF,WAAK,KAAK,GAAG,KAAK,MAAM,MAAM,KAAK;AAAA,IACrC,SAAS,GAAQ;AAGf,WAAK,aAAa,WAAW;AAAA,IAC/B;AAAA,EACF;AAAA,EAEO,MAAM,MAAc,UAAkB,IAAI,IAA4B;AAC3E,SAAK,IAAI,4BAAgB,qBAAS,KAAK,EAAE,MAAM,OAAO,CAAC;AAEvD,QAAI,IAAI;AAGN,cAAQ,SAAS,EAAE;AAAA,IACrB;AAAA,EACF;AAAA,EAEO,MAAM,MAAe,MAAe;AACzC,QAAI,KAAK,eAAe,WAAW,MAAM;AAEvC;AAAA,IACF;AAEA,SAAK,aAAa,WAAW;AAE7B,QAAI,SAAS,QAAW;AACtB,WAAK,KAAK,GAAG,IAAI,MAAM,IAAI;AAAA,IAC7B,OAAO;AACL,WAAK,KAAK,GAAG,MAAM;AAAA,IACrB;AAAA,EACF;AAAA,EAEO,MAAM,MAAe,MAAe;AACzC,uBAAO,KAAK,mEAAmE;AAC/E,QAAI;AACF,YAAM,IAAI,MAAM;AAAA,IAClB,SAAS,GAAQ;AACf,yBAAO,KAAK,EAAE,KAAK;AAAA,IACrB;AACA,SAAK,MAAM,MAAM,IAAI;AAAA,EACvB;AAAA,EAEO,SAAS;AACd,WAAO,EAAE,WAAW,KAAK,WAAW,YAAY,KAAK,WAAW;AAAA,EAClE;AACF;",
"names": ["EventEmitter"]
}