Compare commits

...
2 Commits
4 changed files with 37 additions and 75 deletions
+1 -1
View File
@@ -229,7 +229,7 @@ function handleData(wss, receivedData, rdsWss) {
}).catch((error) => console.log("Error fetching Tx info:", error)); }).catch((error) => console.log("Error fetching Tx info:", error));
// Send the updated data to the client // Send the updated data to the client
const dataToSendJSON = JSON.stringify(dataToSend); const dataToSendJSON = JSON.stringify({...dataToSend, timestamp: Math.floor(Date.now() / 1000) - new Date().getTimezoneOffset() * 60});
if (currentTime - lastUpdateTime >= updateInterval) { if (currentTime - lastUpdateTime >= updateInterval) {
wss.clients.forEach((client) => client.send(dataToSendJSON)); wss.clients.forEach((client) => client.send(dataToSendJSON));
lastUpdateTime = Date.now(); lastUpdateTime = Date.now();
+5 -5
View File
@@ -280,19 +280,19 @@ function resolveDataBuffer(data) {
if (receivedData.length) dataHandler.handleData(wss, receivedData, rdsWss); if (receivedData.length) dataHandler.handleData(wss, receivedData, rdsWss);
} }
function kickClient(ipAddress) { function kickClient(ipAddress) {
// Find the entry in connectedClients associated with the provided IP address
const targetClient = storage.connectedUsers.find(client => client.ip === ipAddress); const targetClient = storage.connectedUsers.find(client => client.ip === ipAddress);
if (targetClient && targetClient.instance) { if (targetClient && targetClient.instance) {
// Send a termination message to the client
targetClient.instance.send('KICK'); targetClient.instance.send('KICK');
// Close the WebSocket connection after a short delay to allow the client to receive the message
setTimeout(() => { setTimeout(() => {
targetClient.instance.close(); targetClient.instance.close();
const index = storage.connectedUsers.indexOf(targetClient);
if (index !== -1) storage.connectedUsers.splice(index, 1);
consoleCmd.logInfo(`Web client kicked (${ipAddress})`); consoleCmd.logInfo(`Web client kicked (${ipAddress})`);
}, 500); }, 750);
} else consoleCmd.logInfo(`Kicking client ${ipAddress} failed. No suitable client found.`); } else consoleCmd.logInfo(`Kicking client ${ipAddress} failed. No suitable client found.`);
} }
+16 -34
View File
@@ -66,20 +66,17 @@ wss.on('connection', (ws, request) => {
// Per-IP limit connection open // Per-IP limit connection open
if (clientIp) { if (clientIp) {
const isLocalIp = (clientIp === '127.0.0.1' || clientIp === '::1' || clientIp.startsWith('192.168.') || clientIp.startsWith('10.') || clientIp.startsWith('172.16.')); if (!ipConnectionCounts.has(clientIp)) ipConnectionCounts.set(clientIp, 0);
if (!isLocalIp) { const currentCount = ipConnectionCounts.get(clientIp);
if (!ipConnectionCounts.has(clientIp)) ipConnectionCounts.set(clientIp, 0); if (currentCount >= MAX_CONNECTIONS_PER_IP) {
const currentCount = ipConnectionCounts.get(clientIp); ws.close(1008, 'Too many open connections from this IP');
if (currentCount >= MAX_CONNECTIONS_PER_IP) { const lastLogTime = ipLogTimestamps.get(clientIp) || 0;
ws.close(1008, 'Too many open connections from this IP'); const now = Date.now();
const lastLogTime = ipLogTimestamps.get(clientIp) || 0; if (now - lastLogTime > IP_LOG_INTERVAL_MS) {
const now = Date.now(); logWarn(`Web client \x1b[31mclosed: limit exceeded\x1b[0m (${clientIp}) \x1b[90m[${currentUsers}]`);
if (now - lastLogTime > IP_LOG_INTERVAL_MS) { ipLogTimestamps.set(clientIp, now);
logWarn(`Web client \x1b[31mclosed: limit exceeded\x1b[0m (${clientIp}) \x1b[90m[${currentUsers}]`); } return;
ipLogTimestamps.set(clientIp, now); } ipConnectionCounts.set(clientIp, currentCount + 1);
} return;
} ipConnectionCounts.set(clientIp, currentCount + 1);
}
} }
if(currentUsers >= MAX_USERS) { if(currentUsers >= MAX_USERS) {
@@ -88,10 +85,7 @@ wss.on('connection', (ws, request) => {
return; return;
} }
if (clientIp !== '127.0.0.1' || if (clientIp !== '127.0.0.1') currentUsers++;
(request.headers && request.headers['origin'] && request.headers['origin'].trim() !== '')) {
currentUsers++;
}
if (timeoutAntenna) clearTimeout(timeoutAntenna); if (timeoutAntenna) clearTimeout(timeoutAntenna);
@@ -170,24 +164,12 @@ wss.on('connection', (ws, request) => {
ws.on('close', (code) => { ws.on('close', (code) => {
// Per-IP limit connection closed // Per-IP limit connection closed
if (clientIp) { if (clientIp) {
const isLocalIp = ( const current = ipConnectionCounts.get(clientIp) || 1;
clientIp === '127.0.0.1' || ipConnectionCounts.set(clientIp, Math.max(0, current - 1));
clientIp === '::1' ||
clientIp.startsWith('192.168.') ||
clientIp.startsWith('10.') ||
clientIp.startsWith('172.16.')
);
if (!isLocalIp) {
const current = ipConnectionCounts.get(clientIp) || 1;
ipConnectionCounts.set(clientIp, Math.max(0, current - 1));
}
} }
if (clientIp !== '127.0.0.1' || if (clientIp !== '127.0.0.1') currentUsers--;
(request.socket && request.socket.remoteAddress && request.socket.remoteAddress !== '::ffff:127.0.0.1') || dataHandler.showOnlineUsers(currentUsers);
(request.headers && request.headers['origin'] && request.headers['origin'].trim() !== '')) {
currentUsers--;
} dataHandler.showOnlineUsers(currentUsers);
const index = storage.connectedUsers.findIndex(user => user.ip === clientIp); const index = storage.connectedUsers.findIndex(user => user.ip === clientIp);
if (index !== -1) storage.connectedUsers.splice(index, 1); if (index !== -1) storage.connectedUsers.splice(index, 1);
+15 -35
View File
@@ -150,8 +150,6 @@ $(document).ready(function () {
return false; return false;
}); });
setInterval(getServerTime, 10000);
getServerTime();
setInterval(sendPingRequest, 5000); setInterval(sendPingRequest, 5000);
sendPingRequest(); sendPingRequest();
@@ -259,37 +257,6 @@ $(document).ready(function () {
initTooltips(); initTooltips();
}); });
function getServerTime() {
$.ajax({
url: "./server_time",
dataType: "json",
success: function(data) {
const serverTimeUtc = data.serverTime;
const options = {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
hour12: false
};
const serverOptions = {
...options,
timeZone: 'Etc/UTC'
};
const formattedServerTime = new Date(serverTimeUtc).toLocaleString(navigator.language ? navigator.language : 'en-US', serverOptions);
$("#server-time").text(formattedServerTime);
},
error: function(jqXHR, textStatus, errorThrown) {
console.error("Error fetching server time:", errorThrown);
}
});
}
function sendPingRequest() { function sendPingRequest() {
const now = Date.now(); const now = Date.now();
@@ -349,8 +316,21 @@ function handleWebSocketMessage(event) {
resetDataTimeout(); resetDataTimeout();
updatePanels(parsedData); updatePanels(parsedData);
const sum = signalData.reduce((acc, strNum) => acc + parseFloat(strNum), 0); data.push(signalData.reduce((acc, strNum) => acc + parseFloat(strNum), 0) / signalData.length);
data.push(sum / signalData.length);
if(parsedData.timestamp) {
const options = {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
hour12: false,
timeZone: 'Etc/UTC'
};
const formattedServerTime = new Date(parsedData.timestamp * 1000).toLocaleString(navigator.language ? navigator.language : 'en-US', options);
$("#server-time").text(formattedServerTime);
}
} }
socket.onmessage = handleWebSocketMessage; socket.onmessage = handleWebSocketMessage;