vybe/server.js

122 lines
2.6 KiB
JavaScript

const fs = require('fs');
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const ioclient = require('socket.io-client');
const compression = require('compression');
const events = {};
for (let file of fs.readdirSync('./src/events')) {
file = require('./src/events/' + file);
for (const event in file)
events[event] = file[event];
}
function rand32() {
let str = '';
const lookups = 'bcdefghjklmnpqrstvwxyz0123456789'.split('');
while (str.length < 16) {
const n = Math.random() * lookups.length;
str += lookups[Math.floor(n)];
}
return str;
}
let instance;
function saveSettings() {
fs.writeFileSync('instance.json', JSON.stringify(instance, null, 2));
}
if (fs.existsSync('instance.json'))
instance = JSON.parse(fs.readFileSync('instance.json'));
else {
instance = {
id: rand32(),
port: process.env.PORT || 1312,
url: process.env.URL || null
};
saveSettings();
}
if (!instance.url)
console.log(
`!! no instance url !
it will be auto-set by the first user authentication !
it can be set in instance.json .`);
global.vybe = {
instance,
saveSettings,
instances: {},
users: {},
threads: {},
streams: {},
connectInstance: async url => {
let instance = vybe.instances[url];
function connecting(resolve, reject) {
instance.socket.on('connect', resolve);
instance.socket.on('connect_error', error => {
instance.socket.disconnect();
reject(error.message);
});
}
if (instance) {
if (!instance.socket.connected) {
instance.socket.connect();
await new Promise(connecting);
}
}
else {
instance = vybe.instances[url] = {
socket: ioclient('https://' + url)
};
await new Promise(connecting);
}
return instance;
}
};
const app = express();
app.use(compression());
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: true
}
});
app.use(express.static('client'));
io.on('connection', (socket) => {
for (let event in events) {
socket.on(event, (msg, callback) => {
if (!events[event]) {
callback('no such event ' + event);
return;
}
try {
events[event](msg, callback, socket);
}
catch (e) {
console.log(`${event} threw exception: `, e);
}
});
}
socket.on('disconnect', reason => {
let user = vybe.users[socket.__userid];
if (user)
user.sockets.splice(user.sockets.indexOf(socket), 1);
for (let id in vybe.streams) {
const stream = vybe.streams[id];
delete stream.listeners[socket.id];
if (stream.socket === socket.id)
stream.stop();
}
});
});
server.listen(instance.port, () => {
console.log('server running on port ' + instance.port);
});