Attempt to not throw exception on server socket error
[vchess.git] / sockets.js
1 const url = require('url');
2 const Variants = require("./variants");
3
4 module.exports = function(wss) {
5
6 let clients = { "index": {} };
7 let games = {}; //pending games (player sid)
8 for (const v of Variants)
9 clients[v.name] = {};
10
11 // // Safety counter (TODO: is it necessary ?)
12 // setInterval(() => {
13 // Object.keys(clients).forEach(k => {
14 // Object.keys(clients[k]).forEach(ck => {
15 // if (!clients[k][ck] || clients[k][ck].readyState != 1)
16 // delete clients[k][ck];
17 // });
18 // });
19 // }, 60000); //every minute (will be lowered if a lot of users...)
20
21 // No-op function as a callback when sending messages
22 const noop = () => { };
23
24 wss.on("connection", (socket, req) => {
25 const params = new URL("http://localhost" + req.url).searchParams;
26 const sid = params.get("sid");
27 const page = params.get("page");
28 clients[page][sid] = socket;
29 if (page == "index")
30 {
31 // Send counting info
32 const countings = {};
33 for (const v of Variants)
34 countings[v.name] = Object.keys(clients[v.name]).length;
35 socket.send(JSON.stringify({code:"counts",counts:countings}));
36 }
37 else
38 {
39 // Send to every client connected on index an update message for counts
40 Object.keys(clients["index"]).forEach( k => {
41 clients["index"][k].send(JSON.stringify({code:"increase",vname:page}), noop);
42 });
43 // Also notify potential opponents: hit all clients which check if sid corresponds
44 Object.keys(clients[page]).forEach( k => {
45 clients[page][k].send(JSON.stringify({code:"connect",id:sid}), noop);
46 });
47 socket.on("message", objtxt => {
48 let obj = JSON.parse(objtxt);
49 switch (obj.code)
50 {
51 case "newmove":
52 if (!!clients[page][obj.oppid])
53 {
54 clients[page][obj.oppid].send(
55 JSON.stringify({code:"newmove",move:obj.move}), noop);
56 }
57 break;
58 case "ping":
59 if (!!clients[page][obj.oppid])
60 socket.send(JSON.stringify({code:"pong"}));
61 break;
62 case "lastate":
63 if (!!clients[page][obj.oppid])
64 {
65 const oppId = obj.oppid;
66 obj.oppid = sid; //I'm oppid for my opponent
67 clients[page][oppId].send(JSON.stringify(obj), noop);
68 }
69 break;
70 case "newgame":
71 if (!!games[page])
72 {
73 // Start a new game
74 const oppId = games[page]["id"];
75 const fen = games[page]["fen"];
76 delete games[page];
77 const mycolor = Math.random() < 0.5 ? 'w' : 'b';
78 socket.send(
79 JSON.stringify({code:"newgame",fen:fen,oppid:oppId,color:mycolor}));
80 if (!!clients[page][oppId])
81 {
82 clients[page][oppId].send(
83 JSON.stringify(
84 {code:"newgame",fen:fen,oppid:sid,color:mycolor=="w"?"b":"w"}),
85 noop);
86 }
87 }
88 else
89 games[page] = {id:sid, fen:obj.fen}; //wait for opponent
90 break;
91 case "resign":
92 if (!!clients[page][obj.oppid])
93 clients[page][obj.oppid].send(JSON.stringify({code:"resign"}), noop);
94 break;
95 }
96 });
97 }
98 socket.on("close", () => {
99 delete clients[page][sid];
100 // Remove potential pending game
101 if (!!games[page] && games[page]["id"] == sid)
102 delete games[page];
103 if (page != "index")
104 {
105 // Send to every client connected on index an update message for counts
106 Object.keys(clients["index"]).forEach( k => {
107 clients["index"][k].send(JSON.stringify({code:"decrease",vname:page}), noop);
108 });
109 }
110 // Also notify potential opponents: hit all clients which check if sid corresponds
111 Object.keys(clients[page]).forEach( k => {
112 clients[page][k].send(JSON.stringify({code:"disconnect",id:sid}), noop);
113 });
114 });
115 });
116 }