123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- let WebSocket = require("ws");
- let createFileServer = require("./filesrv");
- let fs = require("fs");
-
- let datafile = "db.json";
- let scratchfile = ".db.scratch";
-
- let key = process.env.KEY;
- if (!key) {
- console.log("Environmnt variable 'KEY' not set.");
- process.exit(1);
- }
-
- let server = createFileServer("../client/public");
- let wss = new WebSocket.Server({ server });
-
- function deserialize(defaults) {
- try {
- let json = fs.readFileSync(datafile);
- return JSON.parse(json);
- } catch (err) {
- return defaults;
- }
- }
-
- function serialize(data) {
- fs.writeFileSync(scratchfile, JSON.stringify(data));
- fs.renameSync(scratchfile, datafile);
- }
-
- let data = deserialize({
- items: { "0": "foo", "2": "bar" },
- words: {},
- nextIdx: 3,
- });
-
- let conns = [];
- let connID = 0;
-
- function ack(conn, msg, reply = {}) {
- reply.type = "ack";
- reply.ackID = msg.ackID;
-
- conn.sock.send(JSON.stringify(reply));
- }
-
- function broadcast(from, obj) {
- for (let conn of conns) {
- if (!conn) continue;
- if (conn != from)
- conn.sock.send(JSON.stringify(obj));
- }
- }
-
- function onMessage(conn, msg) {
- if (msg.type == "init") {
- if (!msg.key || msg.key != key)
- return ack(conn, msg, { error: "Invalid key." });
-
- ack(conn, msg, { data });
- conn.ready = true;
- conns[conn.id] = conn;
- return;
- }
-
- if (!conn.ready)
- return ack(conn, msg, { error: "Not initialized." });
-
- switch (msg.type) {
- case "item-add":
- if (typeof msg.content != "string")
- return ack(conn, msg, { error: "Missing content." });
-
- let content = msg.content.toLowerCase();
- let index = data.nextIdx.toString();
- data.nextIdx = (data.nextIdx + 1) % 2048;
-
- data.items[index] = content;
-
- if (data.words[content] == null)
- data.words[content] = 0;
- data.words[content] += 1;
-
- ack(conn, msg, { index });
- broadcast(conn, { type: "item-add", content, index });
- serialize(data);
- break;
-
- case "item-del":
- if (typeof msg.index != "string")
- return ack(conn, msg, { error: "Missing index." });
-
- delete data.items[msg.index];
- ack(conn, msg);
- broadcast(conn, { type: "item-del", index: msg.index });
- serialize(data);
- break;
- }
- }
-
- wss.on("connection", sock => {
- let conn = {
- sock,
- ready: false,
- id: connID,
- };
- connID = (connID + 1) % 2048;
-
- sock.on("close", () => {
- delete conns[conn.id];
- });
-
- sock.on("message", msg => {
- let obj;
- try {
- obj = JSON.parse(msg);
- } catch (err) {
- console.error("Client message has invalid JSON:", err);
- console.error(err);
- return;
- }
-
- onMessage(conn, obj);
- });
- });
-
- let port = process.env.PORT ? parseInt(process.env.PORT) : 8080;
- server.listen(port);
- console.log(`Listening on port ${port}.`);
|