48 lines
1.2 KiB
TypeScript
48 lines
1.2 KiB
TypeScript
export interface SSEEventClient {
|
|
send: (data: string) => void;
|
|
events?: Set<string>;
|
|
userId?: number;
|
|
}
|
|
|
|
const clients = new Set<SSEEventClient>();
|
|
|
|
export function subscribe(client: SSEEventClient): () => void {
|
|
clients.add(client);
|
|
return () => clients.delete(client);
|
|
}
|
|
|
|
export function unsubscribe(client: SSEEventClient): void {
|
|
clients.delete(client);
|
|
}
|
|
|
|
export function clientCount(): number {
|
|
return clients.size;
|
|
}
|
|
|
|
export function broadcast(event: string, data: unknown): number {
|
|
const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
|
|
for (const client of clients) {
|
|
if (client.events && !client.events.has(event)) continue;
|
|
try {
|
|
client.send(payload);
|
|
} catch {
|
|
clients.delete(client);
|
|
}
|
|
}
|
|
return clients.size;
|
|
}
|
|
|
|
export function broadcastToUser(event: string, userId: number, data: unknown): number {
|
|
const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
|
|
const targetUserId = Number(userId);
|
|
for (const client of clients) {
|
|
if (client.userId !== targetUserId) continue;
|
|
if (client.events && !client.events.has(event)) continue;
|
|
try {
|
|
client.send(payload);
|
|
} catch {
|
|
clients.delete(client);
|
|
}
|
|
}
|
|
return clients.size;
|
|
}
|