sse => ws
This commit is contained in:
@@ -2,7 +2,6 @@ export * from "./fastify.js";
|
||||
export * from "./homeassistant.js";
|
||||
export * from "./homepage.js";
|
||||
export * from "./logger.js";
|
||||
export * from "./sse.js";
|
||||
export * from "./ws.js";
|
||||
export * from "./tidal.js";
|
||||
export * from "./timehelper.js";
|
||||
|
||||
|
||||
75
src/sse.ts
75
src/sse.ts
@@ -1,75 +0,0 @@
|
||||
import { UUID } from "crypto";
|
||||
import { logInfo } from "./logger.js";
|
||||
|
||||
export type SseClient = {
|
||||
id: UUID;
|
||||
send: (data: SseEvent) => void;
|
||||
};
|
||||
|
||||
export type SseEvent = {
|
||||
type: string;
|
||||
data?: unknown;
|
||||
message?: string;
|
||||
};
|
||||
|
||||
export type SseClientChangeEvent = {
|
||||
type: "add" | "remove";
|
||||
clientId: string;
|
||||
clientCount: number;
|
||||
};
|
||||
|
||||
export type SseClientChangeCallback = (event: SseClientChangeEvent) => void;
|
||||
|
||||
export class SseService {
|
||||
private clients: Map<string, SseClient> = new Map();
|
||||
private clientChangeCallbacks: SseClientChangeCallback[] = [];
|
||||
|
||||
onClientChange(callback: SseClientChangeCallback): () => void {
|
||||
this.clientChangeCallbacks.push(callback);
|
||||
return () => {
|
||||
this.clientChangeCallbacks = this.clientChangeCallbacks.filter(
|
||||
(cb) => cb !== callback,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private emitClientChange(event: SseClientChangeEvent): void {
|
||||
for (const callback of this.clientChangeCallbacks) {
|
||||
callback(event);
|
||||
}
|
||||
}
|
||||
|
||||
addClient(client: SseClient): void {
|
||||
this.clients.set(client.id, client);
|
||||
logInfo(
|
||||
`SSE client connected: ${client.id}. Total clients: ${this.clients.size}`,
|
||||
);
|
||||
this.emitClientChange({
|
||||
type: "add",
|
||||
clientId: client.id,
|
||||
clientCount: this.clients.size,
|
||||
});
|
||||
}
|
||||
|
||||
removeClient(clientId: string): void {
|
||||
this.clients.delete(clientId);
|
||||
logInfo(
|
||||
`SSE client disconnected: ${clientId}. Total clients: ${this.clients.size}`,
|
||||
);
|
||||
this.emitClientChange({
|
||||
type: "remove",
|
||||
clientId,
|
||||
clientCount: this.clients.size,
|
||||
});
|
||||
}
|
||||
|
||||
notifyClients(event: SseEvent): void {
|
||||
for (const client of this.clients.values()) {
|
||||
client.send(event);
|
||||
}
|
||||
}
|
||||
|
||||
getClientCount(): number {
|
||||
return this.clients.size;
|
||||
}
|
||||
}
|
||||
48
src/ws.ts
Normal file
48
src/ws.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user