UNPKG

ksmf

Version:

Modular Microframework for create minimalistic CLI/Web application or REST API

148 lines (135 loc) 4.19 kB
/** * @author Antonio Membrides Espinosa * @email tonykssa@gmail.com * @date 15/11/2021 * @copyright Copyright (c) 2020-2030 * @license GPL * @version 1.0 * @dependencies AppWEB, HttpHandler **/ const http = require('http'); const AppWEB = require('./WEB'); class AppRTA { constructor(option) { this.app = new AppWEB(option); this.sockets = {}; } /** * @description initialize server proxy app */ init() { try { this.app.srvEvent.add(this, 'onLoadModule'); this.app.init(); } catch (error) { this.app.setError(error); } return this; } /** * @description on load module * @param {Object} mod * @param {String} [name] * @param {String} [path] */ onLoadModule(mod, name, path) { this.app.cfg.srv.channel = this.app.cfg.srv.channel || []; if (mod.channels) { this.app.cfg.srv.channel = this.app.cfg.srv.channel.concat(mod.channels); } } /** * @description start app server */ start() { this.run(); } /** * @description stop app server */ stop() { this.app.stop(); } /** * @description run app server */ run() { if (!this.app.web) { this.init(); } const SocketIO = this.app?.helper?.get({ name: 'socket.io', type: 'lib' }); const server = http.createServer(this.app.web); this.wss = new SocketIO.Server(server); this.initConnection(); const listener = server.listen(this.app.cfg.srv.port, (err) => { if (err) { return this.app.setError(err); } const info = listener.address(); this.app.emit('onStart', [{ message: 'SERVER_LISTENING', host: typeof info === "object" ? info.address : info, port: typeof info === "object" ? info.port : this.app.cfg.srv.port }]); }); server.on('error', async (req, res) => { //this.app.setError(err); }); this.server = server; return listener; } initConnection() { const self = this; const channels = this.app.cfg.srv.channel; this.wss.on('connection', (wsc) => { self.initChannels(wsc, channels); self.sockets[wsc.id] = wsc; wsc.on('disconnect', () => { delete self.sockets[wsc.id]; }); }); this.wss.use(async (socket, next) => { if (await self.initAuth(socket, self.wss)) { next(); } }); } /** * @description initialize channels configurations by client * @param {Array} list */ initChannels(wsc, list) { if (!list) return; const self = this; for (let i in list) { const channel = list[i]; wsc.on(channel.route, (body) => { channel.path = channel.path || 'controller'; channel.name = channel.name || channel.controller; const controller = self.app.helper.get(channel); if (!controller || !controller[channel.action]) { self.app.setError(`404 on '${channel.module}:${channel.controller}:${channel.action}'`, wsc, self.wss); } else { controller[channel.action]({ body, ...wsc }, self.wss); } }); } } /** * @description Run authentication handler and get if is valid request or not * @param {Object} req * @param {Object} res * @returns {Promise<boolean>} */ async initAuth(req, res) { const srvAuth = this.app.helper.get('auth'); if (!(srvAuth?.verify instanceof Function)) { return true; } return await srvAuth.verify(req, res); } } module.exports = AppRTA;