Attempt to not throw exception on server socket error
[vchess.git] / sockets.js
index 10a794f..452cb6e 100644 (file)
@@ -1,16 +1,6 @@
-//const url = require('url');
+const url = require('url');
 const Variants = require("./variants");
 
-function getJsonFromUrl(url) {
-       var query = url.substr(2); //starts with "/?"
-       var result = {};
-       query.split("&").forEach(function(part) {
-               var item = part.split("=");
-               result[item[0]] = decodeURIComponent(item[1]);
-       });
-       return result;
-}
-
 module.exports = function(wss) {
 
        let clients = { "index": {} };
@@ -18,21 +8,23 @@ module.exports = function(wss) {
        for (const v of Variants)
                clients[v.name] = {};
 
-       // (resign, newgame, newmove). See https://github.com/websockets/ws/blob/master/lib/websocket.js around line 313
-       // TODO: awaiting newmove, resign, (+newgame?) :: in memory structure (use Redis ?)
-       let newmoves = {};
-       let newresign = {};
-       for (const v of Variants)
-       {
-               newmoves[v.name] = {};
-               newresign[v.name] = {};
-       }
+//     // Safety counter (TODO: is it necessary ?)
+//     setInterval(() => {
+//             Object.keys(clients).forEach(k => {
+//                     Object.keys(clients[k]).forEach(ck => {
+//                             if (!clients[k][ck] || clients[k][ck].readyState != 1)
+//                                     delete clients[k][ck];
+//                     });
+//             });
+//     }, 60000); //every minute (will be lowered if a lot of users...)
+
+       // No-op function as a callback when sending messages
+       const noop = () => { };
 
        wss.on("connection", (socket, req) => {
-               //const params = new URL("http://localhost" + req.url).searchParams;
-               var query = getJsonFromUrl(req.url);
-               const sid = query["sid"]; //params.get("sid");
-               const page = query["page"]; //params.get("page");
+               const params = new URL("http://localhost" + req.url).searchParams;
+               const sid = params.get("sid");
+               const page = params.get("page");
                clients[page][sid] = socket;
                if (page == "index")
                {
@@ -46,36 +38,35 @@ module.exports = function(wss) {
                {
                        // Send to every client connected on index an update message for counts
                        Object.keys(clients["index"]).forEach( k => {
-                               clients["index"][k].send(JSON.stringify({code:"increase",vname:page}));
+                               clients["index"][k].send(JSON.stringify({code:"increase",vname:page}), noop);
                        });
                        // Also notify potential opponents: hit all clients which check if sid corresponds
                        Object.keys(clients[page]).forEach( k => {
-                               clients[page][k].send(JSON.stringify({code:"connect",id:sid}));
+                               clients[page][k].send(JSON.stringify({code:"connect",id:sid}), noop);
                        });
-                       if (!!newmoves[page][sid])
-                       {
-                               socket.send(JSON.stringify({code:"newmove",move:newmoves[page][sid]}));
-                               delete newmoves[page][sid];
-                       }
-                       if (!!newresign[page][sid])
-                       {
-                               socket.send(JSON.stringify({code:"resign"}));
-                               delete newresign[page][sid];
-                       }
                        socket.on("message", objtxt => {
                                let obj = JSON.parse(objtxt);
                                switch (obj.code)
                                {
                                        case "newmove":
-                                               if (!!clients[page][obj.oppid] && clients[page][obj.oppid].readyState == WebSocket.OPEN)
-                                                       clients[page][obj.oppid].send(JSON.stringify({code:"newmove",move:obj.move}));
-                                               else
-                                                       newmoves[page][obj.oppid] = obj.move;
+                                               if (!!clients[page][obj.oppid])
+                                               {
+                                                       clients[page][obj.oppid].send(
+                                                               JSON.stringify({code:"newmove",move:obj.move}), noop);
+                                               }
                                                break;
                                        case "ping":
-                                               if (!!clients[page][obj.oppid] && clients[page][obj.oppid].readyState == WebSocket.OPEN)
+                                               if (!!clients[page][obj.oppid])
                                                        socket.send(JSON.stringify({code:"pong"}));
                                                break;
+                                       case "lastate":
+                                               if (!!clients[page][obj.oppid])
+                                               {
+                                                       const oppId = obj.oppid;
+                                                       obj.oppid = sid; //I'm oppid for my opponent
+                                                       clients[page][oppId].send(JSON.stringify(obj), noop);
+                                               }
+                                               break;
                                        case "newgame":
                                                if (!!games[page])
                                                {
@@ -84,17 +75,22 @@ module.exports = function(wss) {
                                                        const fen = games[page]["fen"];
                                                        delete games[page];
                                                        const mycolor = Math.random() < 0.5 ? 'w' : 'b';
-                                                       socket.send(JSON.stringify({code:"newgame",fen:fen,oppid:oppId,color:mycolor}));
-                                                       clients[page][oppId].send(JSON.stringify({code:"newgame",fen:fen,oppid:sid,color:mycolor=="w"?"b":"w"}));
+                                                       socket.send(
+                                                               JSON.stringify({code:"newgame",fen:fen,oppid:oppId,color:mycolor}));
+                                                       if (!!clients[page][oppId])
+                                                       {
+                                                               clients[page][oppId].send(
+                                                                       JSON.stringify(
+                                                                               {code:"newgame",fen:fen,oppid:sid,color:mycolor=="w"?"b":"w"}),
+                                                                       noop);
+                                                       }
                                                }
                                                else
                                                        games[page] = {id:sid, fen:obj.fen}; //wait for opponent
                                                break;
                                        case "resign":
-                                               if (!!clients[page][obj.oppid] && clients[page][obj.oppid].readyState == WebSocket.OPEN)
-                                                       clients[page][obj.oppid].send(JSON.stringify({code:"resign"}));
-                                               else
-                                                       newresign[page][obj.oppid] = true;
+                                               if (!!clients[page][obj.oppid])
+                                                       clients[page][obj.oppid].send(JSON.stringify({code:"resign"}), noop);
                                                break;
                                }
                        });
@@ -108,12 +104,12 @@ module.exports = function(wss) {
                        {
                                // Send to every client connected on index an update message for counts
                                Object.keys(clients["index"]).forEach( k => {
-                                       clients["index"][k].send(JSON.stringify({code:"decrease",vname:page}));
+                                       clients["index"][k].send(JSON.stringify({code:"decrease",vname:page}), noop);
                                });
                        }
                        // Also notify potential opponents: hit all clients which check if sid corresponds
                        Object.keys(clients[page]).forEach( k => {
-                               clients[page][k].send(JSON.stringify({code:"disconnect",id:sid}));
+                               clients[page][k].send(JSON.stringify({code:"disconnect",id:sid}), noop);
                        });
                });
        });