refactor networking
This commit is contained in:
@@ -19,8 +19,6 @@ export class ConnectionManager {
|
||||
this.connections[key] = {
|
||||
communicator
|
||||
};
|
||||
|
||||
console.log(`Added communicator for ${ip}:${port}, generated public and private keys.`);
|
||||
}
|
||||
|
||||
// Removes a communicator based on IP and port
|
||||
@@ -28,7 +26,6 @@ export class ConnectionManager {
|
||||
const key = `${ip}:${port}`;
|
||||
if (this.connections[key]) {
|
||||
delete this.connections[key];
|
||||
console.log(`Removed communicator for ${ip}:${port}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+30
-31
@@ -3,14 +3,14 @@ import path from 'path';
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
import { ConnectionManager } from './network/connection_manager';
|
||||
import {OperationHandler} from "./network/operations_base/operation_handler";
|
||||
import {GeneralOperations} from "./network/operations_custom/general_operations";
|
||||
import {TcpServerCommunicator} from "./network/socket_communicator/tcp_server_communicator";
|
||||
import {CeoOperations} from "./network/operations_custom/ceo_operations";
|
||||
import {AuthOperations} from "./network/operations_custom/auth_operations";
|
||||
import {DepartmentOperations} from "./network/operations_custom/department_operations";
|
||||
import {KeyOperations} from "./network/operations_custom/key_operations";
|
||||
import {UserOperations} from "./network/operations_custom/user_operations";
|
||||
import { OperationHandler } from "./network/operations_base/operation_handler";
|
||||
import { GeneralOperations } from "./network/operations_custom/general_operations";
|
||||
import { TcpServerCommunicator } from "./network/socket_communicator/tcp_server_communicator";
|
||||
import { CeoOperations } from "./network/operations_custom/ceo_operations";
|
||||
import { AuthOperations } from "./network/operations_custom/auth_operations";
|
||||
import { DepartmentOperations } from "./network/operations_custom/department_operations";
|
||||
import { KeyOperations } from "./network/operations_custom/key_operations";
|
||||
import { UserOperations } from "./network/operations_custom/user_operations";
|
||||
|
||||
dotenv.config({ path: path.resolve(__dirname, './config/.env') });
|
||||
|
||||
@@ -32,60 +32,62 @@ export class TcpServer {
|
||||
this.operationHandler.loadPlugin(new DepartmentOperations());
|
||||
this.operationHandler.loadPlugin(new KeyOperations());
|
||||
this.operationHandler.loadPlugin(new UserOperations());
|
||||
}
|
||||
|
||||
// Unified logging function
|
||||
private log(message: string, level: 'log' | 'error' = 'log'): void {
|
||||
const prefix = '[TcpServer]';
|
||||
if (level === 'error') {
|
||||
console.error(`${prefix} ${message}`);
|
||||
} else {
|
||||
console.log(`${prefix} ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Start the TCP server
|
||||
public start(): void {
|
||||
const tcpServer = net.createServer();
|
||||
|
||||
// Handle incoming connections
|
||||
tcpServer.on('connection', (socket: Socket) => {
|
||||
const ip = socket.remoteAddress || 'unknown';
|
||||
const port = socket.remotePort || 0;
|
||||
const clientId = `${ip}:${port}`;
|
||||
|
||||
const clientId = `${ip}:${port}`; // Use IP and port to identify the client
|
||||
console.log(`Client connected: ${clientId}`);
|
||||
this.log(`Client connected: ${clientId}`);
|
||||
|
||||
const tcpCommunicator = new TcpServerCommunicator(socket, ip, port, this.operationHandler);
|
||||
this.connectionManager.addConnection(ip, port, tcpCommunicator);
|
||||
|
||||
// Generate RSA key pair and start key exchange
|
||||
tcpCommunicator.generateKeyPair();
|
||||
tcpCommunicator.sendPublicKey()
|
||||
.then(() => tcpCommunicator.sendAesKey())
|
||||
.then(() => console.log('Public key and AES key sent successfully.'))
|
||||
.then(() => this.log('Public key and AES key sent successfully.'))
|
||||
.catch(err => {
|
||||
console.error(`Error during key exchange with client ${clientId}:`, err);
|
||||
socket.end(); // Close the connection in case of any error
|
||||
this.log(`Error during key exchange with client ${clientId}: ${err.message}`, 'error');
|
||||
socket.end();
|
||||
});
|
||||
|
||||
// Handle incoming data in chunks
|
||||
socket.on('data', async (data: Buffer) => {
|
||||
await this.handleData(data, ip, port);
|
||||
});
|
||||
|
||||
// Handle client disconnect
|
||||
socket.on('end', () => {
|
||||
console.log(`Client disconnected: ${clientId}`);
|
||||
this.log(`Client disconnected: ${clientId}`);
|
||||
this.connectionManager.removeCommunicator(ip, port);
|
||||
});
|
||||
|
||||
// Handle socket errors
|
||||
socket.on('error', (err: Error) => {
|
||||
console.error(`Error from client ${clientId}: ${err.message}`);
|
||||
this.log(`Error from client ${clientId}: ${err.message}`, 'error');
|
||||
this.connectionManager.removeCommunicator(ip, port);
|
||||
});
|
||||
});
|
||||
|
||||
// Handle server errors
|
||||
tcpServer.on('error', (err: Error) => {
|
||||
console.error(`TCP server error: ${err.message}`);
|
||||
this.log(`TCP server error: ${err.message}`, 'error');
|
||||
});
|
||||
|
||||
// Start listening for connections
|
||||
tcpServer.listen(this.port, this.host, () => {
|
||||
console.log(`TCP server listening on ${this.host}:${this.port}`);
|
||||
this.log(`TCP server listening on ${this.host}:${this.port}`);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -93,17 +95,14 @@ export class TcpServer {
|
||||
private async handleData(data: Buffer, ip: string, port: number): Promise<void> {
|
||||
const clientId = `${ip}:${port}`;
|
||||
|
||||
// Retrieve the communicator associated with this connection
|
||||
const communicator = this.connectionManager.getCommunicator(ip, port) as TcpServerCommunicator;
|
||||
if (!communicator) {
|
||||
console.error(`No communicator found for ${clientId}`);
|
||||
this.log(`No communicator found for ${clientId}`, 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle incoming chunked message via communicator
|
||||
await communicator.handleIncomingChunk(data);
|
||||
|
||||
// Fetch and process result if available
|
||||
const handlerResult = communicator.getHandlerResult();
|
||||
if (handlerResult) {
|
||||
try {
|
||||
@@ -112,9 +111,9 @@ export class TcpServer {
|
||||
handlerResult.metaInfo,
|
||||
handlerResult.fileContent
|
||||
);
|
||||
console.log(`Response sent to ${clientId}`);
|
||||
} catch (err) {
|
||||
console.error(`Failed to send response to ${clientId}:`, err);
|
||||
this.log(`Response sent to ${clientId}`);
|
||||
} catch (err: any) {
|
||||
this.log(`Failed to send response to ${clientId}: ${err.message}`, 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+24
-13
@@ -5,30 +5,39 @@ import { UdpSocketCommunicator } from "./network/socket_communicator/udp_socket_
|
||||
import { OperationHandler } from "./network/operations_base/operation_handler";
|
||||
import { GeneralOperations } from "./network/operations_custom/general_operations";
|
||||
|
||||
dotenv.config({ path: path.resolve(__dirname, './config/.env') });
|
||||
|
||||
export class UdpServer {
|
||||
private readonly udpServer: dgram.Socket;
|
||||
private readonly operationHandler: OperationHandler;
|
||||
private readonly host: string;
|
||||
private readonly port: number
|
||||
private readonly port: number;
|
||||
|
||||
constructor(host: string, port: number) {
|
||||
this.udpServer = dgram.createSocket('udp4');
|
||||
this.operationHandler = OperationHandler.getInstance();
|
||||
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
|
||||
// Load only the GeneralOperations into the operation handler
|
||||
this.operationHandler.loadPlugin(new GeneralOperations());
|
||||
}
|
||||
|
||||
// Unified logging function
|
||||
private log(message: string, level: 'log' | 'error' = 'log'): void {
|
||||
const prefix = '[UdpServer]';
|
||||
if (level === 'error') {
|
||||
console.error(`${prefix} ${message}`);
|
||||
} else {
|
||||
console.log(`${prefix} ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Start the UDP server
|
||||
public start(): void {
|
||||
this.udpServer.on('message', this.handleUdpMessages.bind(this));
|
||||
this.udpServer.on('error', this.handleError);
|
||||
this.udpServer.on('error', this.handleError.bind(this));
|
||||
this.udpServer.on('listening', this.handleListening.bind(this));
|
||||
|
||||
// Bind the server to the UDP port and host
|
||||
this.udpServer.bind(this.port, this.host);
|
||||
}
|
||||
|
||||
@@ -37,31 +46,33 @@ export class UdpServer {
|
||||
const ip = rinfo.address;
|
||||
const port = rinfo.port;
|
||||
|
||||
console.log(`Received message from ${ip}:${port}`);
|
||||
this.log(`Received message from ${ip}:${port}`);
|
||||
|
||||
// Create a temporary communicator for the incoming message
|
||||
const communicator = new UdpSocketCommunicator(this.udpServer, ip, port, this.operationHandler);
|
||||
|
||||
// Process the incoming message using the communicator
|
||||
communicator.handleIncomingMessage(msg.toString());
|
||||
|
||||
const communicatorResult = communicator.getHandlerResult();
|
||||
if (communicatorResult) {
|
||||
// Send response back to the client using the temporary communicator
|
||||
await communicator.sendMessage(communicatorResult.operationCode, communicatorResult.metaInfo);
|
||||
try {
|
||||
await communicator.sendMessage(communicatorResult.operationCode, communicatorResult.metaInfo);
|
||||
this.log(`Response sent to ${ip}:${port}`);
|
||||
} catch (error: any) {
|
||||
this.log(`Error sending response to ${ip}:${port}: ${error.message}`, 'error');
|
||||
}
|
||||
} else {
|
||||
console.error(`No handler result for ${ip}:${port}`);
|
||||
this.log(`No handler result for ${ip}:${port}`, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// Handle UDP server errors
|
||||
private handleError(err: Error): void {
|
||||
console.error(`UDP server error:\n${err.stack}`);
|
||||
this.log(`UDP server error:\n${err.stack}`, 'error');
|
||||
}
|
||||
|
||||
// Handle when the UDP server starts listening
|
||||
private handleListening(): void {
|
||||
const address = this.udpServer.address();
|
||||
console.log(`UDP server listening on ${address.address}:${address.port}`);
|
||||
this.log(`UDP server listening on ${address.address}:${address.port}`);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user