import type { ServerWebSocket } from 'bun'; import { ClientManager } from './src/services/ClientManager.ts'; import { SignalingService } from './src/services/SignalingService.ts'; import type { ISignalingMessage } from './src/interfaces/ISignalingMessage.ts'; import publisherHtml from './public/publisher.html'; import subscriberHtml from './public/subscriber.html'; const clientManager = new ClientManager(); const signalingService = new SignalingService(clientManager); const clientSessions = new Map(); const server = Bun.serve({ port: 3000, routes: { '/': () => new Response(`

WebRTC Broadcasting

Publisher Interface

Subscriber Interface

`, { headers: { 'Content-Type': 'text/html' } }), '/publisher': publisherHtml, '/subscriber': subscriberHtml, }, websocket: { open(ws: ServerWebSocket) { // Store the WebSocket connection without role validation initially // Role will be determined from the first message const clientId = signalingService.handleConnection(ws, 'unknown'); clientSessions.set(ws, clientId); }, message(ws: ServerWebSocket, message: string | Buffer) { const clientId = clientSessions.get(ws); if (!clientId) return; try { const parsedMessage: ISignalingMessage = JSON.parse( typeof message === 'string' ? message : message.toString() ); signalingService.handleMessage(clientId, parsedMessage); } catch (error) { console.error('Failed to parse message:', error); } }, close(ws: ServerWebSocket) { const clientId = clientSessions.get(ws); if (clientId) { signalingService.handleDisconnection(clientId); clientSessions.delete(ws); } } }, development: { hmr: true, console: true } }); console.log(`WebRTC Broadcasting server running on http://localhost:${server.port}`); console.log(`Publisher: http://localhost:${server.port}/publisher`); console.log(`Subscriber: http://localhost:${server.port}/subscriber`);