import cors from "cors"; import express from "express"; import http from "http"; import { Server } from "socket.io"; import { closeDBConnection } from "./database/postgres.js"; import { closeRedisConnection } from "./database/redis.js"; import router from "./routes/router.js"; const port = process.env.PORT ? parseInt(process.env.PORT) : 3000; const app = express(); const httpServer = http.createServer(app); // for Websocket connection const io = new Server(httpServer, { cors: { origin: "*", methods: ["GET", "POST"], }, }); // Global access to Socket.IO server for all controllers app.set("io", io); // Websocket connection handler io.on("connection", (socket) => { console.log(`New Client connected: ${socket.id}`); socket.on("disconnect", () => { console.log(`Client disconnected: ${socket.id}`); }); }); app.use(cors()); app.use(express.json()); app.use(router); let isShuttingDown = false; async function shutdown(exitCode: number) { // Prevent function from being called repeatedly e.g. from nodemon or node --watch if (isShuttingDown) return; isShuttingDown = true; console.log("[SHUTDOWN] Server shutdown initiated..."); // 1. Closing HTTP/WebSocket-Server httpServer.close(async (error) => { if (error) { console.error("Error closing the HTTP server:", error); } else { console.log("Closed HTTP- and WebSocket server."); } // Closing connections to database & Redis await closeDBConnection(); await closeRedisConnection(); // Closing the process console.log("[SHUTDOWN] Process closed."); process.exit(exitCode); }); // Timeout as final fallback if server is unresponsive for 10 seconds setTimeout(() => { console.error("[SHUTDOWN] Timeout! Forcing shutdown."); process.exit(1); }, 10000); } // Listeners for shutdown signals process.on("SIGINT", () => shutdown(0)); // Ctrl+C process.on("SIGTERM", () => shutdown(0)); // Kubernetes, Docker, etc. httpServer.on("error", (error: NodeJS.ErrnoException) => { console.error("Failed to connect to the server...", error); if (error.code === "EADDRINUSE") { console.error(`Port ${port} is already in use.`); } shutdown(1); }); httpServer.listen(port, () => { console.log( `The Robot-Tracker API is activ and listening on port ${port}.` ); console.log("The WebSocket server is active."); });