Suggest using Redis when failing to deliver messages
[vchess.git] / sockets.js
CommitLineData
1d184b4c
BA
1//const url = require('url');
2const Variants = require("./variants");
3
4function getJsonFromUrl(url) {
5 var query = url.substr(2); //starts with "/?"
6 var result = {};
7 query.split("&").forEach(function(part) {
8 var item = part.split("=");
9 result[item[0]] = decodeURIComponent(item[1]);
10 });
11 return result;
12}
13
14module.exports = function(wss) {
15
16 let clients = { "index": {} };
17 let games = {}; //pending games (player sid)
18 for (const v of Variants)
19 clients[v.name] = {};
20
30ff6e04
BA
21 // TODO: when relaying to opponent, check readyState, potential setTimeout()? + send opponent (re)disconnect
22 // (resign, newgame, newmove). See https://github.com/websockets/ws/blob/master/lib/websocket.js around line 313
e5caeff0 23 // TODO: awaiting newmove, resign, newgame :: in memory structure (use Redis ?)
30ff6e04 24
1d184b4c
BA
25 wss.on("connection", (socket, req) => {
26 //const params = new URL("http://localhost" + req.url).searchParams;
27 var query = getJsonFromUrl(req.url);
28 const sid = query["sid"]; //params.get("sid");
29 const page = query["page"]; //params.get("page");
30 clients[page][sid] = socket;
31 if (page == "index")
32 {
33 // Send counting info
34 const countings = {};
35 for (const v of Variants)
36 countings[v.name] = Object.keys(clients[v.name]).length;
37 socket.send(JSON.stringify({code:"counts",counts:countings}));
38 }
39 else
40 {
41 // Send to every client connected on index an update message for counts
42 Object.keys(clients["index"]).forEach( k => {
43 clients["index"][k].send(JSON.stringify({code:"increase",vname:page}));
44 });
45 // Also notify potential opponents: hit all clients which check if sid corresponds
46 Object.keys(clients[page]).forEach( k => {
47 clients[page][k].send(JSON.stringify({code:"connect",id:sid}));
48 });
49 socket.on("message", objtxt => {
50 let obj = JSON.parse(objtxt);
51 switch (obj.code)
52 {
53 case "newmove":
30ff6e04 54 clients[page][obj.oppid].send(JSON.stringify({code:"newmove",move:obj.move}));
1d184b4c
BA
55 break;
56 case "ping":
57 if (!!clients[page][obj.oppid])
58 socket.send(JSON.stringify({code:"pong"}));
59 break;
60 case "newgame":
61 if (!!games[page])
62 {
63 // Start a new game
64 const oppId = games[page]["id"];
65 const fen = games[page]["fen"];
66 delete games[page];
67 const mycolor = Math.random() < 0.5 ? 'w' : 'b';
68 socket.send(JSON.stringify({code:"newgame",fen:fen,oppid:oppId,color:mycolor}));
69 clients[page][oppId].send(JSON.stringify({code:"newgame",fen:fen,oppid:sid,color:mycolor=="w"?"b":"w"}));
70 }
71 else
72 games[page] = {id:sid, fen:obj.fen}; //wait for opponent
73 break;
74 case "resign":
75 clients[page][obj.oppid].send(JSON.stringify({code:"resign"}));
76 break;
77 }
78 });
79 }
80 socket.on("close", () => {
81 delete clients[page][sid];
82 // Remove potential pending game
83 if (!!games[page] && games[page]["id"] == sid)
84 delete games[page];
85 if (page != "index")
86 {
87 // Send to every client connected on index an update message for counts
88 Object.keys(clients["index"]).forEach( k => {
89 clients["index"][k].send(JSON.stringify({code:"decrease",vname:page}));
90 });
91 }
92 // Also notify potential opponents: hit all clients which check if sid corresponds
93 Object.keys(clients[page]).forEach( k => {
94 clients[page][k].send(JSON.stringify({code:"disconnect",id:sid}));
95 });
96 });
97 });
98}