113 lines
4.5 KiB
JavaScript
113 lines
4.5 KiB
JavaScript
import websocket from "websocket";
|
|
import http from "http";
|
|
import {sha512} from "hash-wasm";
|
|
import log from "loglevel";
|
|
|
|
async function start() {
|
|
const logger = log.getLogger("server");
|
|
logger.setLevel("DEBUG", false);
|
|
const WebSocketServer = websocket.server;
|
|
//const http = require('http');
|
|
//const sha512 = require('hash-wasm').sha512;
|
|
const connections = new Map();
|
|
const server = http.createServer(function (request, response) {
|
|
logger.info((new Date()) + ' Received request for ' + request.url);
|
|
response.writeHead(404);
|
|
response.end();
|
|
});
|
|
server.listen(8080, function () {
|
|
logger.info((new Date()) + ' Server is listening on port 8080');
|
|
});
|
|
|
|
const wsServer = new WebSocketServer({
|
|
httpServer: server,
|
|
// You should not use autoAcceptConnections for production
|
|
// applications, as it defeats all standard cross-origin protection
|
|
// facilities built into the protocol and the browser. You should
|
|
// *always* verify the connection's origin and decide whether or not
|
|
// to accept it.
|
|
autoAcceptConnections: false
|
|
});
|
|
|
|
function originIsAllowed(origin) {
|
|
return origin.indexOf('deepdiagram') > -1;
|
|
}
|
|
|
|
wsServer.on('request', async (request) => {
|
|
if (!originIsAllowed(request.origin)) {
|
|
// Make sure we only accept requests from an allowed origin
|
|
request.reject();
|
|
logger.error((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
|
|
return;
|
|
}
|
|
try {
|
|
|
|
const connection = request.accept('echo-protocol', request.origin);
|
|
const hash = await sha512(connection.socket.remoteAddress + '-' + connection.socket.remotePort);
|
|
connections.set(hash, {connection: connection, db: null});
|
|
|
|
|
|
logger.info((new Date()) + ' Connection accepted.', connections.length);
|
|
connections.forEach((conn, key) => {
|
|
if (key != hash) {
|
|
conn.connection.sendUTF('{ "type": "newconnect", "netAttr": "' + hash + '" }');
|
|
}
|
|
});
|
|
|
|
|
|
connection.on('message', function (message) {
|
|
logger.debug(message);
|
|
if (message.type === 'utf8') {
|
|
logger.debug('Received Message: ' + message.utf8Data);
|
|
connections.forEach((conn, index) => {
|
|
const envelope = JSON.parse(message.utf8Data);
|
|
if (index !== hash) {
|
|
if (envelope.db === conn.db) {
|
|
envelope.netAddr = hash;
|
|
conn.connection.sendUTF(JSON.stringify(envelope));
|
|
}
|
|
} else {
|
|
if (!conn.db && envelope.db) {
|
|
conn.db = envelope.db;
|
|
logger.debug('DB set to ' + envelope.db);
|
|
}
|
|
}
|
|
});
|
|
//connection.sendUTF(message.utf8Data);
|
|
} else if (message.type === 'binary') {
|
|
logger.debug('Received Binary Message of ' + message.binaryData.length + ' bytes');
|
|
connections.forEach((conn, index) => {
|
|
if (index !== hash) {
|
|
conn.connection.sendBytes(message.utf8Data);
|
|
}
|
|
});
|
|
}
|
|
|
|
});
|
|
connection.on('close', function (reasonCode, description) {
|
|
connections.delete(hash);
|
|
connections.forEach((conn, index) => {
|
|
conn.connection.sendUTF('{ "type": "close", "netAddr": "' + hash + '" }');
|
|
});
|
|
});
|
|
connection.on('error', function (reasonCode, description) {
|
|
connections.delete(hash);
|
|
connections.forEach((conn, index) => {
|
|
conn.connection.sendUTF('{ "type": "error", "netAddr": "' + hash + '" }');
|
|
});
|
|
logger.info((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.', connections.length);
|
|
});
|
|
setInterval(() => {
|
|
const message = `{ "count": ${connections.size} }`
|
|
logger.debug(message);
|
|
connection.sendUTF(message);
|
|
}, 10000);
|
|
} catch (err) {
|
|
console.log(err);
|
|
}
|
|
|
|
|
|
});
|
|
}
|
|
|
|
start(); |