import express, { Application, Request, Response } from "express"; import * as http from "http"; import * as WebSocket from "ws"; import { HapticLinkServer } from "./socket/hapticLinkServer"; import { registerRoutes } from "./socket/routes"; import WebSocketWrapper from "./socket/WebSocketAdapter"; import pino from "pino"; import path from "path"; (() => { const args = process.argv; if (args.includes("--silent")) { return main(false); } return main(true); })(); function main(logging: boolean = true) { const port: number = parseInt(process.env.PORT as string, 10) || 3000; const logger = pino({ level: logging ? "info" : "silent", formatters: { bindings(bindings) { return { level: bindings.level, time: bindings.time, msg: bindings.msg, }; }, }, }); const app: Application = express(); const server = http.createServer(app); const wss = new WebSocket.Server({ server }); app.use(express.static(path.join(__dirname, "../../client/build/web"))); app.get("*", (_req: Request, res: Response) => { res.sendFile(path.join(__dirname + "/../../client/build/web/index.html")); }); // Routes are in socket/routes/*.ts // registerRoutes imports and adds them all to router const hapticLink = new HapticLinkServer(); registerRoutes(hapticLink); // When a user sends a message, the router checks if that route is available // and then calls the handler. It also generates a User object for them to store // data for later requests such as an ID wss.on("connection", (ws: WebSocket) => { logger.info("Client Connected"); const wsw = new WebSocketWrapper(ws); ws.on("message", (message: string) => { logger.info(`Received Message: ${message}`); hapticLink.handleRoute(wsw, message); }); // When a user disconnects, their account is removed, and they are removed from all groups ws.on("close", () => { hapticLink.removeUser(wsw); }); ws.on("error", () => { hapticLink.removeUser(wsw); }); ws.send("Welcome"); }); server.listen(port, () => { logger.info(`Server is running on port ${port}`); }); }