UNPKG

@colyseus/ws-transport

Version:

```typescript import { Server } from "@colyseus/core"; import { WebSocketTransport } from "@colyseus/ws-transport";

99 lines (78 loc) 2.89 kB
import WebSocket from 'ws'; import { Protocol, ClientState, getMessageBytes, logger, debugMessage, type Client, type ClientPrivate, type ISendOptions, } from '@colyseus/core'; const SEND_OPTS = { binary: true }; export class WebSocketClient implements Client, ClientPrivate { '~messages': any; public id: string; public ref: WebSocket; public sessionId: string; public state: ClientState = ClientState.JOINING; public reconnectionToken: string; public _enqueuedMessages: any[] = []; public _afterNextPatchQueue; public _reconnectionToken: string; public _joinedAt; public _numMessagesLastSecond: number = 0; public _lastMessageTime: number = 0; constructor(id: string, ref: WebSocket) { this.sessionId = this.id = id; this.ref = ref; } public sendBytes(type: string | number, bytes: Buffer | Uint8Array, options?: ISendOptions) { debugMessage("send bytes(to %s): '%s' -> %j", this.sessionId, type, bytes); this.enqueueRaw( getMessageBytes.raw(Protocol.ROOM_DATA_BYTES, type, undefined, bytes), options, ); } public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) { debugMessage("send(to %s): '%s' -> %j", this.sessionId, messageOrType, messageOrOptions); this.enqueueRaw( getMessageBytes.raw(Protocol.ROOM_DATA, messageOrType, messageOrOptions), options, ); } public enqueueRaw(data: Uint8Array | Buffer, options?: ISendOptions) { // use room's afterNextPatch queue if (options?.afterNextPatch) { this._afterNextPatchQueue.push([this, [data]]); return; } if (this.state !== ClientState.JOINED) { // sending messages during `onJoin` or `onReconnect`. // - the client-side cannot register "onMessage" callbacks at this point. // - enqueue the messages to be send after JOIN_ROOM message has been sent // - create a new buffer for enqueued messages, as the underlying buffer might be modified this._enqueuedMessages?.push(data); return; } this.raw(data, options); } public raw(data: Uint8Array | Buffer, options?: ISendOptions, cb?: (err?: Error) => void) { this.ref.send(data, SEND_OPTS, cb); } public error(code: number, message: string = '', cb?: (err?: Error) => void) { this.raw(getMessageBytes[Protocol.ERROR](code, message), undefined, cb); } get readyState() { return this.ref.readyState; } public leave(code?: number, data?: string) { this.ref.close(code, data); } public close(code?: number, data?: string) { logger.warn('DEPRECATION WARNING: use client.leave() instead of client.close()'); try { throw new Error(); } catch (e: any) { logger.info(e.stack); } this.leave(code, data); } public toJSON() { return { sessionId: this.sessionId, readyState: this.readyState }; } }