UNPKG

shardy

Version:

Framework for online games and applications on Node.js

203 lines 8.31 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Server = void 0; const ws_1 = require("ws"); const net_1 = require("net"); const Logger_1 = require("./Logger"); const Tools_1 = require("./Tools"); const Client_1 = require("./Client"); const Transport_1 = require("./Transport"); const Connection_1 = require("./Connection"); const Commander_1 = require("./Commander"); const http_1 = __importDefault(require("http")); const Extension_1 = require("./Extension"); const ID_LENGTH = 10; const CONNECTION_EVENT = 'connection'; const LISTENING_EVENT = 'listening'; const ERROR_EVENT = 'error'; const CLOSE_EVENT = 'close'; const UNCAUGHT_EXCEPTIONS = 'uncaughtException'; const UNHANDLED_REJECTION = 'unhandledRejection'; class Server { constructor(host, port, service, options) { this.host = host; this.port = port; this.service = service; this.options = options; this.log = new Logger_1.Logger([], Tools_1.Tools.getTag(module)); this.list = new Map(); this.extensionsBefore = new Array(); this.extensionsAfter = new Array(); this.catchExceptions(); this.http = http_1.default.createServer(); this.server = this.service.transport === Transport_1.TransportType.TCP ? new net_1.Server() : new ws_1.WebSocketServer({ server: this.http }); this.server.on(CONNECTION_EVENT, (socket, message) => this.onConnect(socket, message)); this.server.on(LISTENING_EVENT, () => this.onListening()); this.server.on(ERROR_EVENT, (error) => this.onError(error)); this.server.on(CLOSE_EVENT, () => this.onClose()); } start() { return __awaiter(this, void 0, void 0, function* () { this.log.info(`${this.service.name} (${this.service.transport}) start`, Logger_1.LoggerScope.System); switch (this.service.transport) { case Transport_1.TransportType.TCP: this.server.listen(this.port, this.host); break; case Transport_1.TransportType.WebSocket: this.http.listen(this.port, this.host); default: break; } }); } stop() { return __awaiter(this, void 0, void 0, function* () { this.log.info(`stop`, Logger_1.LoggerScope.System); this.list.forEach((client) => { client.kick(Commander_1.DisconnectReason.ServerDown); }); this.list.clear(); switch (this.service.transport) { case Transport_1.TransportType.TCP: this.server.close(); break; case Transport_1.TransportType.WebSocket: this.http.close(); default: break; } }); } use(extension) { return __awaiter(this, void 0, void 0, function* () { if (extension.mode === Extension_1.ExtensionMode.Before) { const index = this.extensionsBefore.indexOf(extension, 0); if (index < 0) { yield extension.init(); this.extensionsBefore.push(extension); } } else { const index = this.extensionsAfter.indexOf(extension, 0); if (index < 0) { yield extension.init(); this.extensionsAfter.push(extension); } } this.log.info(`use extension ${extension.name}`, Logger_1.LoggerScope.System); }); } setFilter(filter) { return __awaiter(this, void 0, void 0, function* () { this.log.setFilter(filter); this.list.forEach((client) => { client.log.setFilter(filter); }); this.extensionsBefore.forEach((extension) => { extension.log.setFilter(filter); }); this.extensionsAfter.forEach((extension) => { extension.log.setFilter(filter); }); }); } clearFilter() { return __awaiter(this, void 0, void 0, function* () { this.log.clearFilter(); this.list.forEach((client) => { client.log.clearFilter(); }); this.extensionsBefore.forEach((extension) => { extension.log.clearFilter(); }); this.extensionsAfter.forEach((extension) => { extension.log.clearFilter(); }); }); } onConnect(socket, message) { const ip = message ? message.socket.remoteAddress : socket.remoteAddress; const id = Tools_1.Tools.generateId(ID_LENGTH); const logger = new Logger_1.Logger([id, ip]); logger.setFilter(this.log.getFilter()); const client = new Client_1.Client(new Connection_1.Connection(socket, this.service.transport), id, logger, this.service, this.options); client.onDisconnect = (id, reason) => this.onDisconnect(id, reason); client.onReady = () => this.onReady(client); this.list.set(id, client); this.extensionsBefore.forEach((item) => { item.onClientConnect(client); }); this.service.onConnect(client); this.log.info(`connected ${id}|${ip}`, Logger_1.LoggerScope.Debug); this.extensionsAfter.forEach((item) => { item.onClientConnect(client); }); } onListening() { this.extensionsBefore.forEach((item) => { item.onServiceListening(); }); this.service.onListening(this.host, this.port); this.log.info(`listening on ${this.host}:${this.port}`, Logger_1.LoggerScope.System); this.extensionsAfter.forEach((item) => { item.onServiceListening(); }); } onError(error) { this.service.onError(error); this.log.error(`error: ${error}`, Logger_1.LoggerScope.System); } onClose() { this.extensionsBefore.forEach((item) => { item.onServiceClose(); }); this.service.onClose(); this.log.info(`closed`, Logger_1.LoggerScope.System); this.extensionsAfter.forEach((item) => { item.onServiceClose(); }); } onReady(client) { this.extensionsBefore.forEach((item) => { item.onClientReady(client); }); this.service.onReady(client); this.extensionsAfter.forEach((item) => { item.onClientReady(client); }); } onDisconnect(id, reason) { const client = this.list.get(id); this.extensionsBefore.forEach((item) => { item.onClientDisconnect(client, reason); }); this.service.onDisconnect(client, reason); client.destroy(); this.list.delete(id); this.log.info(`disconnected ${id}`, Logger_1.LoggerScope.Debug); this.extensionsAfter.forEach((item) => { item.onClientDisconnect(client, reason); }); } onException(error) { new Logger_1.Logger([], Tools_1.Tools.getTag(module)).error(`unexpected exception: ${error.stack}`, Logger_1.LoggerScope.All); } catchExceptions() { process.on(UNCAUGHT_EXCEPTIONS, this.onException); process.on(UNHANDLED_REJECTION, this.onException); } } exports.Server = Server; //# sourceMappingURL=Server.js.map