aboutsummaryrefslogtreecommitdiffstats
path: root/lib/sockets.js
blob: 16f422140d0703566d734a17be7f47579ff5ef68 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
const jwt = require("jsonwebtoken");
const uuidv4 = require("uuid/v4");
const WebSocket = require("ws");

wss = new WebSocket.Server({ clientTracking: false, noServer: true });

/* eslint-disable-next-line */
const pick = (O, ...K) => K.reduce((o, k) => ((o[k] = O[k]), o), {});
sockets = {};

emit = (username, type, data) => {
  if (data.username !== undefined) data = pick(data, ...whitelist);

  if (!sockets[username]) return;
  for (id in sockets[username]) {
    const ws = sockets[username][id];
    ws.send(JSON.stringify({ type, data }));
  } 
};

broadcast = (type, data) => {
  for (const username in sockets) {
    for (const id in sockets[username]) {
      const ws = sockets[username][id];
      ws.send(JSON.stringify({ type, data }));
    } 
  };
}

server.on("upgrade", function (request, socket, head) {
  wss.handleUpgrade(request, socket, head, function (ws) {
    wss.emit("connection", ws, request);
  });
});

const names = {};

wss.on("connection", function (ws) {
  const id = uuidv4();

  ws.on("message", async (token) => {
    try {
      const username = jwt.decode(token).username;
      if (!sockets[username]) sockets[username] = {};
      sockets[username][id] = ws;
      names[id] = username;

      ws.send(JSON.stringify({ type: "rates", data: app.get("rates") }));
      ws.send(JSON.stringify({ type: "login", data: await getUser(username) }));
      l.info("socket open", username);
    } catch (e) {
      l.error("problem opening socket", e.message);
    }
  });

  ws.on("close", function () {
    const username = names[id];
    delete sockets[username][id];
    l.info("socket closed", username);
  });
});