204 lines
6.4 KiB
JavaScript
204 lines
6.4 KiB
JavaScript
'use strict';
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const ws_1 = require("ws");
|
|
const express_1 = __importDefault(require("express"));
|
|
const promises_1 = require("fs/promises");
|
|
const path_1 = require("path");
|
|
const uuid_1 = require("uuid");
|
|
const Log = require("log");
|
|
class Server {
|
|
constructor(uiInput) {
|
|
this.id = 'server';
|
|
this.isActive = false;
|
|
this.templates = [
|
|
{
|
|
name: 'index',
|
|
path: 'server.html'
|
|
},
|
|
{
|
|
name: 'script',
|
|
path: 'lib/client/index.js'
|
|
}
|
|
];
|
|
this.port = 9900;
|
|
this.wsPort = 9901;
|
|
this.proxy = {};
|
|
this.queue = {};
|
|
this.intervalPeriod = 10000; //10 sec
|
|
this.init();
|
|
this.ui = uiInput;
|
|
}
|
|
async init() {
|
|
this.log = await Log({ label: this.id });
|
|
await this.load();
|
|
await this.start();
|
|
}
|
|
async load() {
|
|
this.http = express_1.default();
|
|
for (let tmpl of this.templates) {
|
|
tmpl.data = await promises_1.readFile(tmpl.path, 'utf8');
|
|
}
|
|
this.http.get('/', this.index.bind(this));
|
|
this.http.get('/image/:key', this.image.bind(this));
|
|
this.log.info("Server assets loaded");
|
|
}
|
|
template(name, data) {
|
|
let html = this.templates.find(el => el.name === name).data;
|
|
for (let key of Object.keys(data)) {
|
|
html = html.replace(`{{${key}}}`, data[key]);
|
|
}
|
|
return html;
|
|
}
|
|
async startWss() {
|
|
try {
|
|
this.wss = new ws_1.WebSocketServer({ port: this.wsPort });
|
|
}
|
|
catch (err) {
|
|
this.log.error(err);
|
|
return;
|
|
}
|
|
this.wss.on('connection', async function (ws, req) {
|
|
const address = req.socket.remoteAddress;
|
|
ws.on('message', function (data) {
|
|
let obj = JSON.parse(data);
|
|
//this.log.info(data)
|
|
if (obj.id && this.queue[obj.id]) {
|
|
this.queue[obj.id](obj);
|
|
delete this.queue[obj.id];
|
|
if (obj.action !== 'ping') {
|
|
this.log.info(`${obj.action} ACK`);
|
|
}
|
|
}
|
|
}.bind(this));
|
|
ws.on('close', function () {
|
|
this.log.info('Client disconnected');
|
|
this.notify('Client disconnected', `No longer forwarding digital display to client ${address}`);
|
|
}.bind(this));
|
|
await this.cmd(ws, 'mcopy');
|
|
this.log.info('Client connected');
|
|
this.notify('Client connected', `Forwarding digital display to client: ${address}`);
|
|
}.bind(this));
|
|
this.log.info(`Websocket server started!`);
|
|
this.log.info(`WSS [ ws://localhost:${this.wsPort} ]`);
|
|
}
|
|
async startHttp() {
|
|
return new Promise(function (resolve, reject) {
|
|
this.httpd = this.http.listen(this.port, function () {
|
|
this.log.info(`HTTP server started!`);
|
|
this.log.info(`URL [ http://localhost:${this.port} ]`);
|
|
return resolve(true);
|
|
}.bind(this));
|
|
}.bind(this));
|
|
}
|
|
async start() {
|
|
await this.startHttp();
|
|
await this.startWss();
|
|
this.interval = setInterval(async function () {
|
|
await this.cmdAll('ping');
|
|
}.bind(this), this.intervalPeriod);
|
|
this.isActive = true;
|
|
}
|
|
async stopHttp() {
|
|
return new Promise(function (resolve, reject) {
|
|
return this.httpd.close(function () {
|
|
this.log.info(`HTTP server stopped :(`);
|
|
return resolve(false);
|
|
}.bind(this));
|
|
}.bind(this));
|
|
}
|
|
async stop() {
|
|
await this.stopHttp();
|
|
clearInterval(this.interval);
|
|
this.isActive = false;
|
|
}
|
|
index(req, res, next) {
|
|
const SCRIPT = this.template('script', { PORT: `${this.wsPort}` });
|
|
const html = this.template('index', { SCRIPT });
|
|
this.log.info('GET /');
|
|
return res.send(html);
|
|
}
|
|
async image(req, res, next) {
|
|
let filePath;
|
|
if (req.params && req.params.key) {
|
|
if (this.proxy[req.params.key]) {
|
|
filePath = this.proxy[req.params.key].path;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
return new Promise(function (resolve, reject) {
|
|
return res.sendFile(filePath, function (err) {
|
|
if (err) {
|
|
res.status(err.status).end();
|
|
return reject(err);
|
|
}
|
|
return resolve(true);
|
|
});
|
|
}.bind(this));
|
|
}
|
|
addProxy(key, filePath) {
|
|
//wipe every time
|
|
this.proxy = {};
|
|
this.proxy[key] = {
|
|
path: filePath
|
|
};
|
|
this.log.info(`Added proxy image [${key}]`);
|
|
}
|
|
async cmdAll(action, options = {}) {
|
|
const cmds = [];
|
|
if (this.useServer()) {
|
|
this.wss.clients.forEach(function (ws) {
|
|
cmds.push(this.cmd(ws, action, options));
|
|
}.bind(this));
|
|
await Promise.all(cmds);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
async displayImage(src) {
|
|
let key;
|
|
if (this.useServer()) {
|
|
key = path_1.basename(src);
|
|
this.addProxy(key, src);
|
|
await this.cmdAll('image', { image: `/image/${key}` });
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
useServer() {
|
|
return this.isActive && this.wss.clients.size > 0;
|
|
}
|
|
/**
|
|
* WSS
|
|
**/
|
|
async cmd(ws, action, options = {}) {
|
|
const id = uuid_1.v4();
|
|
let obj = {
|
|
id, action
|
|
};
|
|
let str;
|
|
obj = Object.assign(obj, options);
|
|
str = JSON.stringify(obj);
|
|
ws.send(str);
|
|
return new Promise(function (resolve, reject) {
|
|
this.queue[id] = function (obj) {
|
|
return resolve(obj);
|
|
};
|
|
//setTimeout() ?
|
|
}.bind(this));
|
|
}
|
|
notify(title, message) {
|
|
this.ui.send('gui', { notify: { title, message } });
|
|
}
|
|
}
|
|
module.exports = function (ui) {
|
|
return new Server(ui);
|
|
};
|
|
//# sourceMappingURL=index.js.map
|