import config from "config"; import {Express, Router} from "express"; import {WebSocketServer} from "ws"; import Application from "../Application.js"; import ApplicationComponent from "../ApplicationComponent.js"; import {logger} from "../Logger.js"; import WebSocketListener from "../WebSocketListener.js"; import ExpressAppComponent from "./ExpressAppComponent.js"; import RedisComponent from "./RedisComponent.js"; export default class WebSocketServerComponent extends ApplicationComponent { private wss?: WebSocketServer; public async init(): Promise { const app = this.getApp(); app.require(ExpressAppComponent); app.require(RedisComponent); } public async initRoutes(router: Router): Promise { router.use((req, res, next) => { res.locals.websocketUrl = config.get('app.public_websocket_url'); next(); }); } public async start(_app: Express): Promise { const app = this.getApp(); const listeners: { [p: string]: WebSocketListener } = app.getWebSocketListeners(); this.wss = new WebSocketServer({ server: app.as(ExpressAppComponent).getServer(), }, () => { logger.info(`Websocket server started over webserver.`); }).on('error', (err) => { logger.error(err, 'An error occurred in the websocket server.'); }).on('connection', (socket, request) => { const listener = request.url ? listeners[request.url] : null; if (!listener) { socket.close(1002, `Path not found ${request.url}`); return; } logger.debug(`Websocket on ${request.url}`); listener.handle(socket, request).catch(err => { logger.error(err, 'Error in websocket listener.'); }); }); } public async stop(): Promise { const wss = this.wss; if (wss) { await this.close('WebSocket server', callback => wss.close(callback)); } } }