blob: c0ffd8e3a21c9b562503fafce117f5207bc0adda (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
import { WebSocketServer, WebSocket } from 'ws';
import type { Server } from 'http';
let wss: WebSocketServer;
interface Subscription {
ws: WebSocket;
projects: Set<string>;
}
const subscriptions: Subscription[] = [];
export function setupWebSocket(server: Server): void {
wss = new WebSocketServer({ server, path: '/ws' });
wss.on('connection', (ws) => {
const sub: Subscription = { ws, projects: new Set() };
subscriptions.push(sub);
ws.on('message', (data) => {
try {
const msg = JSON.parse(data.toString());
if (msg.type === 'subscribe' && msg.project) {
sub.projects.add(msg.project);
} else if (msg.type === 'unsubscribe' && msg.project) {
sub.projects.delete(msg.project);
}
} catch {
// ignore malformed messages
}
});
ws.on('close', () => {
const idx = subscriptions.indexOf(sub);
if (idx !== -1) subscriptions.splice(idx, 1);
});
});
}
export function broadcast(project: string, event: Record<string, unknown>): void {
const payload = JSON.stringify(event);
for (const sub of subscriptions) {
if (sub.projects.has(project) && sub.ws.readyState === WebSocket.OPEN) {
sub.ws.send(payload);
}
}
}
export function broadcastAll(event: Record<string, unknown>): void {
const payload = JSON.stringify(event);
for (const sub of subscriptions) {
if (sub.ws.readyState === WebSocket.OPEN) {
sub.ws.send(payload);
}
}
}
|