Spaces:
Paused
Paused
File size: 3,896 Bytes
58ad246 ebf3f0c cfd4c95 2b43822 35fc662 a74716b 34ecf0f cfd4c95 58ad246 a74716b d32b1fb cfd4c95 d32b1fb a74716b cfd4c95 58ad246 a74716b c0563d6 d32b1fb cfd4c95 d32b1fb a74716b 58ad246 34ecf0f 58ad246 34ecf0f d32b1fb a74716b d32b1fb 2b43822 d32b1fb c0563d6 d32b1fb cfd4c95 c0563d6 d32b1fb a74716b c0563d6 58fc009 d32b1fb e3cb794 d32b1fb e3cb794 c0563d6 d32b1fb a74716b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
/*
Created by Anne Lefebvre and Anuj Panthri - 2023
Handles the HTTP file serving and the WebSocket connect for HapticTouch
*/
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";
// If started with --silent, then logging will be disabled.
(() => {
const args = process.argv;
if (args.includes("--silent")) {
return main(false);
}
return main(true);
})();
/**
* Starts HTTP(S) and WS server, initializes HapticLinkServer and handles routing.
* @param {boolean} logging - Defaults true
*/
function main(logging: boolean = true) {
// Added by Anuj
const PING_INTERVAL = parseInt(process.env.PING_INTERVAL as string, 10) || 5 * 1000;
interface LooseWebSocket extends WebSocket {
isAlive?: boolean
}
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 });
// The entire build/web directory is statically served.
app.use(express.static(path.join(__dirname, "../../client/build/web")));
// Catch all. If we want to add pages later, then we should probably change this.
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: LooseWebSocket) => {
logger.info("Client Connected");
const wsw = new WebSocketWrapper(ws);
ws.isAlive = true; // Added by Anuj
ws.on("message", (message: string) => {
logger.info(`Received Message: ${message}`);
hapticLink.handleRoute(wsw, message);
});
// Added by Anuj
// When receive pong from a client this is triggered
ws.on('pong', () => {
ws.isAlive = true;
logger.info("received pong");
});
// Added by Anuj
// When receive ping from a client this is triggered
ws.on('ping', () => {
logger.info("received ping");
});
// 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");
});
// Added by Anuj
const interval = setInterval(function ping() {
wss.clients.forEach((ws) => {
const client = ws as LooseWebSocket;
if (client.isAlive === false) return ws.terminate();
ws.ping();
client.isAlive = false;
});
}, PING_INTERVAL);
// Added by Anuj
wss.on('close', function close() {
clearInterval(interval);
});
server.listen(port, () => {
logger.info(`Server is running on port ${port}`);
});
}
|