Files
FACULTATE-LICENTA/User/src/helpers/network_scanner.ts
T
2024-11-12 14:00:30 +02:00

186 lines
7.6 KiB
TypeScript

import {JsonManager} from "./json_manager";
import {UdpClient} from "../network/udp/udp_client";
import {parentPort} from "worker_threads";
import {TcpCommunicator} from "./tcp_communicator";
import {operationCodes} from "../network/operation_codes";
import {ParsedMessage} from "../network/message_handler";
export class NetworkScanner {
private applicationInfo: JsonManager;
private userConfig: JsonManager;
private readonly udpPort: number;
private readonly tcpPort: number;
private readonly okPage: string;
private readonly errorPage: string;
private readonly databaseResetPage: string;
private appStarted = false;
private intervalIds: NodeJS.Timeout[] = [];
// Flags to prevent overlapping executions
private ucCheckBusy = false;
private ipLookupBusy = false;
private sendLoginBusy = false;
constructor(applicationInfoPath: string, userConfigPath: string, udpPort: number, tcpPort: number, okPage: string, errorPage: string, databaseResetPage: string) {
this.applicationInfo = new JsonManager(applicationInfoPath);
this.userConfig = new JsonManager(userConfigPath);
this.udpPort = udpPort;
this.tcpPort = tcpPort;
this.okPage = okPage;
this.errorPage = errorPage;
this.databaseResetPage = databaseResetPage;
// Start tasks
this.startUCCheck();
this.startUserIPLookup();
this.sendLoginRequest();
}
// Log helper function for consistent logging format
private log(message: string, level: 'log' | 'error' = 'log', methodName: string = ''): void {
const prefix = `[NetworkScanner${methodName ? `.${methodName}` : ''}]`;
if (level === 'error') {
console.error(`${prefix} ${message}`);
} else {
console.log(`${prefix} ${message}`);
}
}
// UC Check Task
private startUCCheck(interval: number = 5000): void {
const intervalId = setInterval(async () => {
if (this.ucCheckBusy) return;
this.ucCheckBusy = true;
try {
this.log('UC Check running...', 'log', 'startUCCheck');
const udpClient = new UdpClient(this.udpPort);
const aliveClients = await udpClient.getAliveClients();
const storedIp = await this.applicationInfo.readValue('serverIp');
const foundClient = aliveClients.length > 0;
if (foundClient) {
const ipAddress = aliveClients[0]; // Use the first alive client
if (!storedIp || storedIp !== ipAddress) {
await this.applicationInfo.writeValue('serverIp', ipAddress);
if (!this.appStarted) {
parentPort?.postMessage({ type: 'changeContent', page: this.okPage });
}
this.appStarted = true;
} else if (!this.appStarted) {
parentPort?.postMessage({ type: 'changeContent', page: this.okPage });
this.appStarted = true;
}
} else {
parentPort?.postMessage({ type: 'changeContent', page: this.errorPage });
}
} catch (err) {
this.log(`Error checking UC: ${err}`, 'error', 'startUCCheck');
parentPort?.postMessage({ type: 'changeContent', page: this.errorPage });
} finally {
this.ucCheckBusy = false;
}
}, interval);
this.intervalIds.push(intervalId);
}
// IP Lookup Task
private startUserIPLookup(interval: number = 10000): void {
const intervalId = setInterval(async () => {
if (this.ipLookupBusy) return;
this.ipLookupBusy = true;
try {
this.log('IP Lookup running...', 'log', 'startUserIPLookup');
const serverIp = await this.applicationInfo.readValue('serverIp');
const udpClient = new UdpClient(this.udpPort);
const activeIPs = await udpClient.getAliveClients();
const filteredIPs = activeIPs.filter(ip => ip !== serverIp);
// Save the filtered IPs to 'users_ip'
await this.applicationInfo.writeValue('users_ip', filteredIPs);
} catch (err) {
this.log(`Error during user IP lookup: ${err}`, 'error', 'startUserIPLookup');
} finally {
this.ipLookupBusy = false;
}
}, interval);
this.intervalIds.push(intervalId);
}
// Login Request Task
private sendLoginRequest(interval: number = 5000): void {
const intervalId = setInterval(async () => {
if (this.sendLoginBusy || this.appStarted) return;
this.sendLoginBusy = true;
try {
const userInfo = await this.userConfig.readValue('user_info');
if (!userInfo || !userInfo.email || !userInfo.password) {
this.log("Email or password not found in user config.", 'error', 'sendLoginRequest');
return;
}
const app_type = await this.userConfig.readValue('app_type');
const email = userInfo.email;
const password = userInfo.password;
const serverIp = await this.applicationInfo.readValue('serverIp');
if (!serverIp) {
this.log("Server IP not found in application info.", 'error', 'sendLoginRequest');
return;
}
const tcpCommunicator = new TcpCommunicator(serverIp, this.tcpPort);
if (!await tcpCommunicator.connect()) {
this.log("Failed to connect to the server.", 'error', 'sendLoginRequest');
return;
}
const metaInfo = { email, password, app_type };
if (!await tcpCommunicator.sendMessage(operationCodes.LOGIN, metaInfo)) {
this.log("Failed to send login request.", 'error', 'sendLoginRequest');
await tcpCommunicator.disconnect();
return;
}
const response = await this.waitForResponse(tcpCommunicator);
if (response?.operationCode !== operationCodes.OK) {
await this.userConfig.resetFile();
await this.userConfig.writeValue('app_type', app_type);
parentPort?.postMessage({ type: 'changeContent', page: this.databaseResetPage });
}
} catch (err) {
this.log(`Error during login request: ${err}`, 'error', 'sendLoginRequest');
} finally {
this.sendLoginBusy = false;
}
}, interval);
this.intervalIds.push(intervalId);
}
// Helper function to wait for a response from the TCP communicator
private async waitForResponse(tcpCommunicator: TcpCommunicator): Promise<ParsedMessage | null> {
return new Promise((resolve) => {
const checkInterval = setInterval(() => {
if (tcpCommunicator.hasResponseArrived()) {
clearInterval(checkInterval);
resolve(tcpCommunicator.getLastResult());
}
}, 100);
});
}
// Method to stop all intervals (for cleanup if needed)
public stopAllIntervals(): void {
for (const id of this.intervalIds) {
clearInterval(id);
}
this.log("All intervals have been stopped.", 'log', 'stopAllIntervals');
}
}