mirror of
https://github.com/KubaPro010/fm-dx-webserver.git
synced 2026-07-31 01:09:18 +02:00
send time in messages, and also make sure that there are no phantom users (it will happen when a user's connection is suddenly stopped, or their ip changes)
This commit is contained in:
@@ -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)});
|
||||||
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
@@ -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
@@ -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
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user