import crypto from 'crypto' import { Flaska, QueryHandler } from 'flaska' import { WebSocket, WebSocketServer } from 'ws' import { startup } from './ffmpeg/startup.mjs' import Monitor from './ffmpeg/monitor.mjs' import ServeHandler from './serve.mjs' export function run(http, port, core) { let localUtil = new core.sc.Util(import.meta.url) // Create our server const flaska = new Flaska({ log: core.log, }, http) flaska.before(function(ctx) { ctx.state.started = new Date().getTime() }) // flaska.after(function(ctx) { let ended = new Date().getTime() var requestTime = ended - ctx.state.started let status = '' let level = 'info' if (ctx.status >= 400) { status = ctx.status + ' ' level = 'warn' } if (ctx.status >= 500) { level = 'error' } ctx.log[level]({ duration: requestTime, status: ctx.status, }, `<-- ${status}${ctx.method} ${ctx.url}`) }) const serve = new ServeHandler({ root: localUtil.getPathFromRoot('../public'), }) flaska.get('/::file', serve.serve.bind(serve)) return flaska.listenAsync(port).then(function() { core.log.info('Server is listening on port ' + port) const wss = new WebSocketServer({ server: flaska.server }) const encoder = startup(core) const monitor = new Monitor(wss, core.db, encoder) monitor.start() monitor.on('status', (status) => { wss.clients.forEach(function each(client) { if (!client.readyState === WebSocket.OPEN) { console.log('closed', client) } client.sendevent('status', status); }) }) wss.on('connection', function(ws) { ws.id = crypto.randomBytes(6).toString('base64') ws.isAlive = true core.log.info({ id: ws.id, ip: ws._socket.remoteAddress }, 'New connection') ws.on('pong', function() { ws.isAlive = true }) ws.sendevent = function(type, data) { ws.send(JSON.stringify({ type: type, payload: data, })) } ws.sendevent('status', monitor.status()) ws.on('message', function message(data, isBinary) { if (isBinary) { return console.log('got binary, not supported') } let payload try { payload = JSON.parse(data.toString()) } catch (err) { core.log.error(err) return } if (!payload.type || typeof(payload.type) !== 'string') { core.log.error(new Error('Got payload but it was missing type: ' + data.toString())) return } console.log('got', payload.type, payload.payload) /*wss.clients.forEach(function each(client) { if (client.readyState === WebSocket.OPEN) { client.send(JSON.stringify(payload)); } })*/ }) }) const interval = setInterval(function() { wss.clients.forEach(function(ws) { if (ws.isAlive === false) { return ws.terminate() } ws.isAlive = false ws.ping() }) }, 15000) wss.on('close', function() { console.log('closing') clearInterval(interval) }) }) }