UNPKG

@x5e/gink

Version:

an eventually consistent database

89 lines 3.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SimpleServer = void 0; const Database_1 = require("./Database"); const Peer_1 = require("./Peer"); const buffer_1 = require("buffer"); const Listener_1 = require("./Listener"); const utils_1 = require("./utils"); /** * A server that connects all inbound websocket connections to a single database instance. */ class SimpleServer extends Database_1.Database { constructor(store, args) { super(store, args.identity, args.logger || (() => null)); this.listener = new Listener_1.Listener(Object.assign({ requestHandler: this.onRequest.bind(this), requestListener: this.requestListener.bind(this), index: "/static/dashboard/dashboard.html" }, args)); this.connections = new Map(); this.authFunc = args.authFunc || (() => true); this.ready = Promise.all([this.ready, this.listener.ready]).then(() => args.logger(`SimpleServer.ready`)); } async onRequest(request) { await this.ready; const thisServer = this; // pass into closures let protocol = null; let token = null; if (request.requestedProtocols.length) { for (const protocol of request.requestedProtocols) { if (protocol.match(/0x.*/)) { token = (0, utils_1.decodeToken)(protocol); } } if (request.requestedProtocols.includes(Database_1.Database.PROTOCOL)) protocol = Database_1.Database.PROTOCOL; else return request.reject(400, "bad protocol"); } if (!this.authFunc(token)) { return request.reject(401, "authentication failed"); } const connection = request.accept(protocol, request.origin); this.logger(`Connection accepted.`); const sendFunc = (data) => { connection.sendBytes(buffer_1.Buffer.from(data)); }; const closeFunc = () => { connection.close(); }; const connectionId = this.createConnectionId(); this.connections.set(connectionId, connection); const peer = new Peer_1.Peer(sendFunc, closeFunc); this.peers.set(connectionId, peer); connection.on("close", function (_reasonCode, _description) { thisServer.peers.delete(connectionId); thisServer.connections.delete(connectionId); thisServer.logger(" Peer " + connection.remoteAddress + " disconnected."); }); connection.on("message", this.onMessage.bind(this, connectionId)); sendFunc(this.iHave.getGreetingMessageBytes()); } onMessage(connectionId, webSocketMessage) { if (webSocketMessage.type === "utf8") { this.logger("Received Text Message: " + webSocketMessage.utf8Data); } else if (webSocketMessage.type === "binary") { this.logger("Server received binary message of " + webSocketMessage.binaryData.length + " bytes."); this.receiveMessage(webSocketMessage.binaryData, connectionId).catch((reason) => this.logger(reason)); } } requestListener(request, response) { const connectTo = this.connectTo.bind(this); if (request.url.startsWith("/api/connections")) { if (request.method === "GET") { let connections = Object.fromEntries(this.connections); response.end(JSON.stringify(connections)); } if (request.method === "POST") { request.addListener("data", async function (chunk) { await connectTo(chunk); }); } } else { this.listener.requestListener(request, response); } } } exports.SimpleServer = SimpleServer; //# sourceMappingURL=SimpleServer.js.map