manus4oHER's picture
Upload folder using huggingface_hub
eee16fe verified
Raw
History Blame Contribute Delete
3.26 kB
import { createServer, Server as SocketServer, Socket } from 'node:net';
import Connection from '@/core/interface/networking/Connection';
import Logger from '@/core/infra/logger/Logger';
import { PacketMapValue } from '@/core/interface/networking/packets/Packets';
import { GameConfig } from '@/game/infra/config/GameConfig';
import { ConnectionStateEnum } from '@/core/enum/ConnectionStateEnum';
export default abstract class Server {
protected server!: SocketServer;
protected readonly connections = new Map<string, Connection>();
protected readonly logger: Logger;
protected readonly config: GameConfig;
protected readonly container: any;
protected readonly packets: Map<number, PacketMapValue<any>>;
protected isShuttingDown = false;
constructor(container: { logger: Logger; config: GameConfig; packets: Map<number, PacketMapValue<any>> }) {
this.logger = container.logger;
this.config = container.config;
this.container = container;
this.packets = container.packets;
}
setup() {
this.server = createServer(this.onListener.bind(this));
return this;
}
abstract createConnection(socket: Socket): Connection;
abstract onData(connection: Connection, data: Buffer): Promise<void>;
onListener(socket: Socket) {
socket.setNoDelay(true);
const connection = this.createConnection(socket);
this.connections.set(connection.getId(), connection);
this.logger.debug(`[IN][CONNECT SOCKET EVENT] New connection: ID: ${connection.getId()}`);
connection.startHandShake();
socket.on('close', this.onClose.bind(this, connection));
socket.on('data', this.onData.bind(this, connection));
socket.on('error', this.onError.bind(this, connection));
}
async onError(connection: Connection, err: Error) {
this.logger.debug(`[IN][ERROR SOCKET EVENT] Closing connection: ID: ${connection.getId()}`);
this.logger.debug(`[IN][ERROR SOCKET EVENT] Error ${err.message || err}`);
connection.setState(ConnectionStateEnum.CLOSE);
}
async onClose(connection: Connection) {
this.logger.debug(`[IN][CLOSE SOCKET EVENT] Closing connection: ID: ${connection.getId()}`);
this.connections.delete(connection.getId());
}
start(): Promise<void> {
return new Promise((resolve) => {
this.server.listen(this.config.SERVER_PORT, Number(this.config.SERVER_ADDRESS), () => {
this.logger.info(`Server running on: ${this.config.SERVER_ADDRESS}:${this.config.SERVER_PORT} 🔥 `);
resolve();
});
});
}
async close(): Promise<void> {
if (!this.server.listening || this.isShuttingDown) return;
this.isShuttingDown = true;
return new Promise((resolve, reject) => {
this.server.close((err: Error | undefined) => {
if (err) {
this.logger.error('[SERVER] Error when try to close server:', err);
reject(err);
} else {
this.logger.info('[SERVER] Server closed with success.');
resolve();
}
});
});
}
}