/** * @author Martin Karkowski * @email m.karkowski@zema.de * @create date 2020-11-06 08:52:42 * @modify date 2021-03-01 17:43:12 * @desc [description] */ import { Server } from "http"; import * as io from "socket.io"; import { generateId } from "../../helpers/idMethods"; import { getNopeLogger } from "../../logger/getLogger"; import { LoggerLevel } from "../../logger/nopeLogger"; import { Bridge } from "../bridge"; import { EventLayer } from "./eventLayer"; /** * Communication Layer using IO-Sockets. * * @export * @class IoSocketServer * @implements {ICommunicationInterface} */ export class IoSocketServer extends Bridge { protected _socket: io.Server; protected _sockets: Set; /** * Creates an instance of IoSocketServer. * @param {number} port The Port, on which the Server should be hosted * @param {("mirror" | "default")} [mode="default"] The Mode of the Server (it could be either a mirror-server or default-server) * @param {LoggerLevel} [level="info"] Logger Level of the Layer * @param {Server} [server] A Server shich should be used. (Otherwise a Server is created) * @memberof IoSocketServer */ constructor( public port: number, level: LoggerLevel = "info", server?: Server ) { super(generateId(), "socket-io-server", level); // If a server has been provided, we will use this, otherwise, // we will create one. if (server) { this._socket = (io as any)(server); } else { this._socket = (io as any)(); } const _this = this; this.connected.setContent(false); this._logger.info( "waiting for connection. Listening on port: " + port.toString() ); this._socket.listen(port); this._socket.on("connection", (client) => { _this._logger.info("New Connection established: " + client.id); // 1. Define a Custom Logger for the Client: const logger = getNopeLogger("io-client-" + client.id, "info"); // 2. Create the Layer. Based on the Mode it will be either an Mirror or Default Layer. const layer = new EventLayer(client as any, logger); // 3. Add the Layer this.addLayer(layer, true); // Subscribe to Loosing connection: client.on("disconnect", () => { _this._logger.info("Connection of : " + client.id + " lost."); _this._sockets.delete(client); // Manually Remove the Layer _this.removeLayer(layer); if (_this._sockets.size === 0) { _this.connected.setContent(false); _this._logger.warn("All Connections lost"); } }); _this.connected.forcePublish(); }); this._sockets = new Set(); } async dispose() { // Dispose the Connection Flag. this.connected.dispose(); // Dispose every connection. for (const client of this._sockets) { client.disconnect(); } } }