| 21 | type AnyCallback<T, U extends number> = (event: T, type: U, args: any[]) => void |
| 22 | |
| 23 | export class SocketClient<SOCKET extends BaseSocket> { |
| 24 | api: SocketAPIData<BackOut, BackOutTemplate, EVENT> = create_api(); |
| 25 | |
| 26 | /** If true, do not attempt to reconnect */ |
| 27 | abortReconnects = false; |
| 28 | |
| 29 | /** Kill self if connection ever fully dies (can't reconnect) */ |
| 30 | killOnDisconnect = false; |
| 31 | |
| 32 | client: SocketServerClient<BackIn, BackInTemplate, SOCKET> = { |
| 33 | id: -1, // Unused (only used by servers) |
| 34 | next_id: 0, |
| 35 | sent: [], |
| 36 | socket: undefined, |
| 37 | }; |
| 38 | |
| 39 | url = ''; |
| 40 | secret = ''; |
| 41 | /** Constructor of the socket used by this. */ |
| 42 | socketCon: SocketConstructor<SOCKET>; |
| 43 | /** If the socket should be kept open. */ |
| 44 | keepOpen = false; |
| 45 | |
| 46 | /** Callbacks for when the socket starts listening. */ |
| 47 | protected when_listeners: (() => void)[] = []; |
| 48 | |
| 49 | constructor( |
| 50 | socketCon: SocketConstructor<SOCKET>, |
| 51 | private onFatal?: () => void, |
| 52 | public onStateChange?: (open: boolean) => void, |
| 53 | ) { |
| 54 | this.socketCon = socketCon; |
| 55 | } |
| 56 | |
| 57 | /** Resolves when the socket starts listening. If it is already listening this is resolved immediately. */ |
| 58 | whenListening(): Promise<void> { |
| 59 | return new Promise((resolve) => { |
| 60 | if (this.client.socket && this.client.socket.readyState === WebSocket.OPEN) { |
| 61 | resolve(); |
| 62 | } else { |
| 63 | this.when_listeners.push(resolve); |
| 64 | } |
| 65 | }); |
| 66 | } |
| 67 | |
| 68 | setSocket(socket: SOCKET): void { |
| 69 | this.keepOpen = true; |
| 70 | this.client.socket = socket; |
| 71 | this.client.socket.onmessage = this.onMessage.bind(this); |
| 72 | this.client.socket.onerror = this.onError.bind(this); |
| 73 | this.client.socket.onclose = this.onClose.bind(this); |
| 74 | this.client.socket.onopen = this.onOpen.bind(this); |
| 75 | this.ensureConnection(); |
| 76 | } |
| 77 | |
| 78 | listen(socket: SOCKET): void { |
| 79 | this.unlisten(); |
| 80 |
nothing calls this directly
no test coverage detected