/** * @author Martin Karkowski * @email m.karkowski@zema.de * @create date 2021-03-22 19:03:15 * @modify date 2022-01-03 17:34:13 * @desc [description] */ import * as io from "socket.io"; import { defineNopeLogger, ValidLoggerDefinition, } from "../../logger/getLogger"; import { DEBUG, INFO } from "../../logger/index.browser"; import { Eventnames } from "../../types/nope"; import { EventCommunicationInterface } from "./EventCommunicationInterface"; /** * Mirror Layer using IO-Sockets. * * @export * @class IoSocketMirrorServer */ export class ioSocketServerLayer extends EventCommunicationInterface { protected _sockets: Set; /** * Creates an instance of IoSocketMirrorServer. * @author M.Karkowski * @param {number} port Port the Server is running on. * @param {ValidLoggerDefinition} [logger="info"] * @memberof IoSocketMirrorServer */ constructor(public port: number, logger: ValidLoggerDefinition = "info") { super( // As event Emitter, we provide the IO-Client. (io as any)({ cors: { origin: "*", methods: ["GET", "POST"], }, }), defineNopeLogger(logger, "core.mirror.io-srv") ); const _this = this; // Tell the Server to listen. (this._emitter as any).listen(port); // Now, because we arent connected we set the connected flag to false, // it will only be true, if a connection with this server has been established this.connected.getter = () => { return true; }; if (_this._logger?.enabledFor(INFO)) { this._logger.info("Hosting Server on Port " + port.toString()); } (this._emitter as any).on("connection", (client) => { if (_this._logger?.enabledFor(INFO)) { _this._logger.info("New Connection established: " + client.id); } _this._sockets.add(client); // Now Subscribe the Events and make shure we // are forwarding the data. for (const event of Eventnames) { client.on(event, (data) => { if (event !== "StatusChanged" && _this._logger?.enabledFor(DEBUG)) { _this._logger.debug( "forwarding", "'" + event.toString() + "'", data ); } _this._forward(client, event, data); }); } // Subscribe to Loosing connection: client.on("disconnect", () => { if (_this._logger?.enabledFor(INFO)) { _this._logger.info("Connection of : " + client.id + " lost."); } _this._sockets.delete(client); // Force an Update of the connect-flag _this.connected.forcePublish(); }); // Force an Update of the connect-flag _this.connected.forcePublish(); }); this._sockets = new Set(); } /** * Helper Function, to forward events to the other connected Sockets. * * @protected * @param {io.Socket} socket The socket, which initally received the data. * @param {string} event the event which was received * @param {*} data the data, that needs to be forwarded * @memberof IoSocketMirrorServer */ protected _forward(socket: io.Socket, event: string, data: any): void { // Flag, used to Debug let forwarded = false; for (const socketToForward of this._sockets) { if (socket !== socketToForward) { socketToForward.emit(event, data); // If data has been sended, our flag is set to true forwarded = true; } } // Now we log the output if (event !== "StatusUpdate" && this._logger?.enabledFor(DEBUG)) { this._logger.debug( forwarded ? "forwarded" : "didnt forward", "'" + event.toString() + "'", data ); } } dispose(): Promise { // Disposes the Emitter. return new Promise((resolve, reject) => { (this._emitter as any as io.Server).removeAllListeners(); (this._emitter as any as io.Server).close((err) => { if (err) reject(err); else resolve(); }); }); } }