bfcache: server - Implement WebSocket server functionality

* Added WebSocketServer class with configurable options
* Introduced WebSocketServerFactory for creating WebSocket relay servers
* Updated index.ts to set up a server with WebSocket support and handle various signals for graceful shutdown
This commit is contained in:
2025-09-18 17:49:07 -04:00
parent 8f9813e735
commit 804f2d990a
3 changed files with 80 additions and 8 deletions

View File

@@ -1 +1,36 @@
console.log('hello claris');
import {LoggerFactory} from '@techniker-me/logger';
import WebSocketServerFactory from './net/websockets/WebSocketServerFactory';
LoggerFactory.setLoggingLevel('All');
const webSocketRelayServer = WebSocketServerFactory.createWebSocketRelayServer();
const PORT = parseInt(process.env.PORT || '4444', 10);
const server = Bun.serve({
port: PORT,
fetch: (request, server) => {
if (server.upgrade(request)) {
return;
}
return new Response('hi');
},
websocket: webSocketRelayServer
});
process.on('SIGINT', () => {
console.log('Received [SIGINT] stopping server');
server.stop();
});
process.on('SIGKILL', () => {
console.log('Received [SIGKILL] stopping server');
server.stop();
});
process.on('SIGTERM', () => {
console.log('Received [SIGTERM] stopping server');
server.stop();
});
console.log(`Server listening on [:${server.port}]`);

View File

@@ -1,5 +1,5 @@
import type {ServerWebSocket, WebSocketCompressor} from 'bun';
import type {Seconds, Bytes} from './types/Units';
import type {Seconds, Bytes} from '../../types/Units';
export type PerMessageDeflate =
| boolean

View File

@@ -0,0 +1,37 @@
import {LoggerFactory} from '@techniker-me/logger';
import WebSocketServer, {WebSocketServerOptions} from './WebSocketServer';
import {ServerWebSocket} from 'bun';
export default class WebSocketServerFactory {
public static createWebSocketRelayServer(): WebSocketServer {
const logger = LoggerFactory.getLogger('WebSocketRelayServer');
const clients = new Set<ServerWebSocket>();
const webSocketRelayServerOptions: WebSocketServerOptions = {
onSocketError: (client, error) => logger.error(`Error: [%o] [${error.message}]`, client),
onSocketOpen: client => {
logger.debug('New WebSocketClient [%o]', client);
clients.add(client);
},
onSocketMessage: (fromClient, message) => {
logger.debug(`Relaying message [%o]`, message);
for (const client of clients) {
if (client === fromClient) {
continue;
}
client.send(message);
}
},
onSocketClose: client => clients.delete(client),
onSocketDrain: client => logger.debug('Client drain [%o]', client),
publishToSelf: false
};
return new WebSocketServer(webSocketRelayServerOptions);
}
private constructor() {
throw new Error('WebSocketServerFactory is a static class that may not be instantiated');
}
}