From 1db846daa320eb5113a49b3bcddd5c9a79ddd36a Mon Sep 17 00:00:00 2001 From: STEINNI Date: Sun, 21 Jun 2026 21:08:04 +0000 Subject: [PATCH] a whole bunch of things --- actions/utilities.js | 17 ++++++++++++----- configSchema.json | 5 +++-- p42wssGateway.js | 21 +++++++++++++-------- startWssGw.sh | 6 +++++- wssConnexion.js | 9 ++++++++- wssGatewayConfig.json | 22 ++++++++-------------- wssServer.js | 14 +++++++------- 7 files changed, 56 insertions(+), 38 deletions(-) diff --git a/actions/utilities.js b/actions/utilities.js index 07d8ae3..abbf12a 100644 --- a/actions/utilities.js +++ b/actions/utilities.js @@ -8,11 +8,18 @@ export const methods = { { "action": "PONG", } - */ - action_PONG(action, payload){ - clearTimeout(this.keepAliveBomb); - this.keepAliveNextTimeout = setTimeout(this.keepAlive.bind(this),this.config.server.keepAliveInterval*1000); - }, + */ + action_PONG(action, payload, reqid){ + + if(reqid == this.latestPing.id) { + console.log('====>PONG', reqid, this.latestPing, Date.now() - this.latestPing.time) + this.roundTripTime = (this.roundTripTime + (Date.now() - this.latestPing.time)) / 2 //Exponential smoothing + } + // First defuse the bomb + clearTimeout(this.keepAliveBomb) + // Then setup the next one ;-) + this.keepAliveNextTimeout = setTimeout(this.keepAlive.bind(this),this.config.server.keepAliveInterval*1000); + }, /* Request: diff --git a/configSchema.json b/configSchema.json index 1b1fa68..df06a7f 100644 --- a/configSchema.json +++ b/configSchema.json @@ -117,8 +117,9 @@ "listenPath": { "type": "string" }, "unsecure": { "type": "boolean" }, "challengeExpiration": { "type": "integer" }, - "keepAliveInterval": { "type": "string" }, - "keepAliveTimeout": { "type": "string" } + "keepAliveInterval": { "type": "number" }, + "keepAliveTimeout": { "type": "number" }, + "refreshSessionInterval": { "type": "number" } }, "required": [ "challengeExpiration", diff --git a/p42wssGateway.js b/p42wssGateway.js index a9a474f..6cde716 100644 --- a/p42wssGateway.js +++ b/p42wssGateway.js @@ -31,21 +31,26 @@ const mysqlCreds = { // host: '127.0.0.1', // port: 3306, socketPath: '/var/run/mysqld/mysqld.sock', - user: 'p42', - password: 'C3h=V9!r>Mvc>skxPf9?W2P3duJTk', - database: 'p42', + user: process.env.mysql_user, + password: process.env.mysql_pass, + database: 'p42GUI', waitForConnections: true, connectionLimit: 10, queueLimit: 0 } +if(!mysqlCreds.user || !mysqlCreds.password) { + console.error('Missing MySQL credentials: set mysql_user and mysql_pass in environment') + process.exit(1) +} + const db = await mysql.createConnection(mysqlCreds) const sessionStore = new MySQLStore({ createDatabaseTable: false, clearExpired: true, schema: { - tableName: 'p42_sessions', + tableName: 'sessions', columnNames: { session_id: 'session_id', expires: 'expires', @@ -84,12 +89,12 @@ async function startAllRedis(wssGatewayConfig) { ) const loginResults = await Promise.allSettled( redisConns.map(async cnx => { - cnx.redisLogin() + await cnx.redisLogin() return cnx.redisId }) ) - 2. //make sure all connected before going any further + //2. make sure all connected before going any further const failedLogin = loginResults.filter(r => r.status !== 'fulfilled') if (failedLogin.length > 0) { console.error('Redis login failures:') @@ -107,7 +112,7 @@ async function startAllRedis(wssGatewayConfig) { // --- Phase 2: start channels for all (since all succeeded) const chanResults = await Promise.allSettled( redisConns.map(async cnx => { - cnx.redisChansStart() + await cnx.redisChansStart() return cnx.redisId }) ) @@ -172,7 +177,7 @@ cfgh.fetchConfig().then( async wssGatewayConfig => { return } WSSServer.handleUpgrade(req, socket, head, (ws) => { - ws.session = req.session // direct access to Express session + ws.session = req.session // Caution : that one is turned in stone, not alive ! WSSServer.emit('connection', ws, req) }) }) diff --git a/startWssGw.sh b/startWssGw.sh index 79d9158..d9fdcb7 100755 --- a/startWssGw.sh +++ b/startWssGw.sh @@ -1,11 +1,15 @@ #!/bin/sh +set -a +. /etc/p42/secrets.env +set +a + cd /opt/p42wssGateway/ pid=`ps -ef | grep p42wssGateway |grep -v grep | awk '{print $2}'` if [ -z "$pid" ] then - node p42wssGateway.js > wssGateway.log 2>&1 & + node p42wssGateway.js --debug > wssGateway.log 2>&1 & else echo '' echo 'Already running PID='"$pid"' (use stopWssGw.sh to stop it)' diff --git a/wssConnexion.js b/wssConnexion.js index f546e0d..3a68ec9 100644 --- a/wssConnexion.js +++ b/wssConnexion.js @@ -17,6 +17,7 @@ export class WssConnexion { this.userId = options.userId this.roles = options.roles this.sessionID = null // null until login + this.roundTripTime = 0 this.subscriptions = []; this.usersWatched = []; @@ -58,7 +59,7 @@ export class WssConnexion { } if(typeof this['action_'+action] == "function") { - if((this.debug) && (action != 'PONG')) console.warn(`${action} for uuid ${this.uuid}`); + if((this.debug) && (action != 'PONG rcv')) console.warn(`${action} for uuid ${this.uuid}`); this['action_'+action](action, payload, reqid); } else { if(this.debug) console.warn(`Unknown action ${action} for UUID ${this.uuid}`); @@ -72,9 +73,15 @@ export class WssConnexion { keepAlive(){ + this.latestPing = { + id: crypto.randomUUID(), + time: Date.now() + } this.send(JSON.stringify({ 'action': 'PING', + 'reqid': this.latestPing.id, })); + console.log('====>PING sent', this.latestPing) this.keepAliveBomb = setTimeout(this.MissedKeepAlive.bind(this), (this.config.server.keepAliveTimeout+1)*1000); } diff --git a/wssGatewayConfig.json b/wssGatewayConfig.json index 772579a..6a56d5a 100644 --- a/wssGatewayConfig.json +++ b/wssGatewayConfig.json @@ -4,8 +4,9 @@ "listenHost": "127.0.0.1", "listenPort": 3999, "listenPath": "/msgbus", - "keepAliveInterval": "30", - "keepAliveTimeout": "5", + "keepAliveInterval": 30, + "keepAliveTimeout": 5, + "refreshSessionInterval": 600, "XXcertFile": "/etc/letsencrypt/live/42.internike.com/fullchain.pem", "XXcertKeyFile": "/etc/letsencrypt/live/42.internike.com/privkey.pem", "challengeExpiration": 20, @@ -14,20 +15,13 @@ "accessRights":[ { "roles": "*", - "mustSubscribe": [ "system:notifs:[UID]", "system:notifs" ], - "canSubscribe": ["system:gps:*", "arena:gps:*","arena:agents:*"], - "canPublish": [ ], + "mustSubscribe": [ "system:notifs:[UID]", "system:notifs", "system:replies:[UID]" ], + "canSubscribe": ["system:gps:*", "arena:gps:*","arena:agents:*", + "system:observer:subscribed[UID]:agents", + "system:maestro:lifecycle:[UID]"], + "canPublish": [ "system:requests:*", "system:observer:requests"], "canSet": [ ], "canGet": [ ] - }, - { - "roles": ["admin"], - "mustSubscribe": ["system:infraNotifs", "system:replies:[UID]"], - "canSubscribe": [ ], - "canPublish": [ "system:requests:*" ], - "canSet": ["system:*"], - "canGet": ["system:*"], - "canDo": ["getActiveUsers", "reloadAccessRights", "getAccessRights"] } ], "redis":[ diff --git a/wssServer.js b/wssServer.js index af711e0..3888165 100644 --- a/wssServer.js +++ b/wssServer.js @@ -92,13 +92,13 @@ export class wssServer { return(OnlineUsers); } - sessionConnected(sessionID){ - if(!sessionID) return(false) // If that cnx is not finished login-in - for(let uuid in this.AllWssConnections) { - if(this.AllWssConnections[uuid].sessionID==sessionID) return(true) - } - return(false) - } + // sessionConnected(sessionID){ + // if(!sessionID) return(false) // If that cnx is not finished login-in + // for(let uuid in this.AllWssConnections) { + // if(this.AllWssConnections[uuid].sessionID==sessionID) return(true) + // } + // return(false) + // } async reloadAccessRights() { await this.configHelper.refreshAccessRights()