50 lines
1.1 KiB
TypeScript
50 lines
1.1 KiB
TypeScript
import type { WebSocket } from "ws";
|
|
import { logInfo } from "./logger.js";
|
|
|
|
export type WsEvent = {
|
|
type: string;
|
|
data?: unknown;
|
|
};
|
|
|
|
export type WsClientChangeCallback = (clients: number) => void;
|
|
|
|
export class WsService {
|
|
private clients: Set<WebSocket> = new Set();
|
|
private listeners: WsClientChangeCallback[] = [];
|
|
|
|
onClientChange(callback: WsClientChangeCallback): () => void {
|
|
this.listeners.push(callback);
|
|
return () => {
|
|
this.listeners = this.listeners.filter((cb) => cb !== callback);
|
|
};
|
|
}
|
|
|
|
private emitClientChange(): void {
|
|
for (const callback of this.listeners) {
|
|
callback(this.clients.size);
|
|
}
|
|
}
|
|
|
|
addClient(ws: WebSocket): void {
|
|
this.clients.add(ws);
|
|
logInfo(`Socket connected. Total clients: ${this.clients.size}`);
|
|
this.emitClientChange();
|
|
}
|
|
|
|
removeClient(ws: WebSocket): void {
|
|
this.clients.delete(ws);
|
|
logInfo(`Socket disconnected. Total clients: ${this.clients.size}`);
|
|
this.emitClientChange();
|
|
}
|
|
|
|
broadcast(message: WsEvent): void {
|
|
this.clients.forEach((socket) => {
|
|
socket.send(JSON.stringify(message));
|
|
});
|
|
}
|
|
|
|
getClientCount(): number {
|
|
return this.clients.size;
|
|
}
|
|
}
|