// SPDX-License-Identifier: GPL-3.0-or-later // Author: Sascha Nitsch https://contentnation.net/@grumpydevelop import { createServer, Server } from 'http'; import { MonitorWS } from './monitor'; import { RobotWS } from './robot'; import { WorldSim } from '../worldsim'; import fs from 'fs'; class MyWebSocketServer { private server: Server; private monitor: MonitorWS; private robot: RobotWS; constructor(worldSim: WorldSim) { this.server = createServer(); this.monitor = new MonitorWS({ noServer: true }); this.robot = new RobotWS({ noServer: true }, worldSim); worldSim.setMonitors(this.monitor); worldSim.setRobots(this.robot); } start() { this.server.on('request', (request, res) => { const { pathname } = new URL(request.url || '', 'ws://base.url'); let filename = 'htdocs' + pathname; if (pathname.endsWith('/')) { filename += 'index.html'; } try { const stream = fs.createReadStream(filename); stream.on("error", () => { res.statusCode = 404; res.end("Not found"); console.log("404", filename); }); stream.on("open", () => { if (filename.endsWith('.html')) { res.setHeader("Content-Type", "text/html"); } else if (filename.endsWith('.css')) { res.setHeader("Content-Type", "text/css"); } else if (filename.endsWith('.js')) { res.setHeader("Content-Type", "text/javascript"); } stream.pipe(res); }); } catch (e) { request.statusCode = 404; } }); this.server.on('upgrade', (request, socket, head) => { const { pathname } = new URL(request.url || '', 'ws://base.url'); if (pathname === '/monitor') { this.monitor.handleUpgrade(request, socket, head, (ws) =>{ this.monitor.emit('connection', ws, request); }); } else if (pathname === '/robot') { this.robot.handleUpgrade(request, socket, head, (ws) => { this.robot.emit('connection', ws, request); }); } else { console.log("nope"); socket.destroy(); } }); this.server.listen(3000); } async stop() { this.server.closeAllConnections(); // await this.httpTerminator.terminate(); } } export { MyWebSocketServer }