This commit is contained in:
ctrlcn
2025-11-20 02:41:30 -05:00
parent fb3c91221c
commit 698fb19014
7 changed files with 185 additions and 35 deletions

View File

@@ -8,8 +8,9 @@ import { isIP } from 'net';
import { IPDataManager } from '../../IPData.js';
import WSClient from './WSClient.js';
import { User } from '../../User.js';
import pino from 'pino';
import { pino, type Logger } from 'pino';
import { BanManager } from '../../BanManager.js';
import { v4 as uuid4 } from 'uuid';
const kAllowedProtocols = [
"guacamole" // Regular ol' collabvm1 protocol
@@ -20,17 +21,25 @@ export default class WSServer extends EventEmitter implements NetworkServer {
private wsServer: WebSocketServer;
private clients: WSClient[];
private Config: IConfig;
private logger = pino({ name: 'CVMTS.WSServer' });
private logger: Logger;
private banmgr: BanManager;
private uuid: string;
constructor(config: IConfig, banmgr: BanManager) {
super();
this.Config = config;
this.clients = [];
this.uuid = uuid4();
this.logger = pino().child({
stream: 'CVMTS.WSServer',
"uuid/websocket/server": this.uuid,
node: config.collabvm.node,
});
this.httpServer = http.createServer();
this.wsServer = new WebSocketServer({ noServer: true, perMessageDeflate: false, clientTracking: false });
this.httpServer.on('upgrade', (req: http.IncomingMessage, socket: internal.Duplex, head: Buffer) => this.httpOnUpgrade(req, socket, head));
this.httpServer.on('request', (req, res) => {
this.logger.debug({ event: "request", path: req.url });
res.writeHead(426);
res.write('This server only accepts WebSocket connections.');
res.end();
@@ -39,13 +48,33 @@ export default class WSServer extends EventEmitter implements NetworkServer {
}
start(): void {
this.logger.info({
event: "websocket server starting",
host: this.Config.http.host,
port: this.Config.http.port,
});
this.httpServer.listen(this.Config.http.port, this.Config.http.host, () => {
this.logger.info(`WebSocket server listening on ${this.Config.http.host}:${this.Config.http.port}`);
this.logger.info({
event: "websocket server started",
host: this.Config.http.host,
port: this.Config.http.port,
});
});
}
stop(): void {
this.httpServer.close();
this.logger.info({
event: "websocket server stopping",
host: this.Config.http.host,
port: this.Config.http.port,
});
this.httpServer.close(() => {
this.logger.info({
event: "websocket server stopped",
host: this.Config.http.host,
port: this.Config.http.port,
});
});
}
private async httpOnUpgrade(req: http.IncomingMessage, socket: internal.Duplex, head: Buffer) {
@@ -142,17 +171,34 @@ export default class WSServer extends EventEmitter implements NetworkServer {
}
private onConnection(ws: WebSocket, req: http.IncomingMessage, ip: string, protocol: string) {
let client = new WSClient(ws, ip);
const uuid = uuid4();
const connectionId = {
"uuid/websocket/client": uuid,
src_ip: ip
};
this.logger.info({ ...connectionId, event: "websocket client connecting" });
let client = new WSClient(ws, ip, uuid);
this.clients.push(client);
let user = new User(client, protocol, IPDataManager.GetIPData(ip), this.Config);
this.logger.info({
...connectionId,
event: "websocket client connection bound to user",
"uuid/user": user.uuid
});
this.emit('connect', user);
ws.on('error', (e) => {
this.logger.error(`${e} (caused by connection ${ip})`);
this.logger.error({ ...connectionId, event: "websocket connection error" });
ws.close();
});
this.logger.info(`New WebSocket connection from ${user.IP.address}`);
ws.on('close', () => {
this.logger.error({ ...connectionId, event: "websocket connection closed" });
});
this.logger.info({ ...connectionId, event: "websocket client connected" });
}
}