| const { Server } = require("socket.io"); |
|
|
| |
| const port = 7860; |
| const io = new Server(port, { |
| cors: { |
| origin: "*", |
| } |
| }); |
|
|
| let activeUsers = 0; |
| const userSessions = {}; |
| const userSessionHistory = []; |
|
|
| |
| function isPrivateIP(ip) { |
| const parts = ip.split('.').map(part => parseInt(part, 10)); |
| if (parts.length !== 4) return false; |
| const [a, b] = parts; |
|
|
| return ( |
| a === 10 || |
| (a === 172 && b >= 16 && b <= 31) || |
| (a === 192 && b === 168) || |
| a === 127 || |
| a === 0 |
| ); |
| } |
|
|
| async function fetchIpInfo(ip) { |
| try { |
| const controller = new AbortController(); |
| const timeout = setTimeout(() => controller.abort(), 5000); |
|
|
| const res = await fetch(`https://ipinfo.io/${ip}/json`, { |
| signal: controller.signal, |
| }); |
|
|
| clearTimeout(timeout); |
|
|
| if (!res.ok) throw new Error(`HTTP error ${res.status}`); |
| return await res.json(); |
| } catch (e) { |
| if (e.name === 'AbortError') { |
| console.error("IP info fetch timed out for IP:", ip); |
| } else { |
| console.error("IP info fetch failed:", e); |
| } |
| return null; |
| } |
| } |
|
|
| io.on("connection", async (socket) => { |
| if (socket.handshake.query.isAdmin === "true") { |
| |
| socket.emit("userSessionHistory", userSessionHistory); |
|
|
| |
| socket.emit("updateUserCount", activeUsers); |
| socket.emit("userSessionsUpdate", userSessions); |
|
|
| return; |
| } |
|
|
| console.log(`New connection from ${socket.id}, isAdmin: ${socket.handshake.query.isAdmin}`); |
|
|
| activeUsers++; |
|
|
| |
| let ips = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address; |
| if (typeof ips === 'string') { |
| ips = ips.split(',').map(ip => ip.trim()); |
| } else { |
| ips = [ips]; |
| } |
|
|
| const ipString = ips.join(', '); |
| const connectTime = new Date(); |
|
|
| userSessions[socket.id] = { |
| socketId: socket.id, |
| ip: ipString, |
| connectTime, |
| disconnectTime: null, |
| loc: null, |
| city: null, |
| region: null, |
| country: null, |
| }; |
|
|
| |
| const firstPublicIp = ips.find(ip => ip && !isPrivateIP(ip)); |
| if (firstPublicIp) { |
| const ipInfo = await fetchIpInfo(firstPublicIp); |
| if (ipInfo) { |
| userSessions[socket.id].loc = ipInfo.loc || null; |
| userSessions[socket.id].city = ipInfo.city || null; |
| userSessions[socket.id].region = ipInfo.region || null; |
| userSessions[socket.id].country = ipInfo.country || null; |
| } |
| } |
|
|
| io.emit("updateUserCount", activeUsers); |
| io.emit("userSessionsUpdate", userSessions); |
|
|
| socket.on("disconnect", () => { |
| activeUsers--; |
| const disconnectTime = new Date(); |
|
|
| if (userSessions[socket.id]) { |
| userSessions[socket.id].disconnectTime = disconnectTime; |
|
|
| |
| userSessionHistory.push({ ...userSessions[socket.id] }); |
|
|
| |
| } |
|
|
| io.emit("updateUserCount", activeUsers); |
| io.emit("userSessionsUpdate", userSessions); |
| }); |
| }); |