Small fix + attempt to improve socket messages reliability...
[vchess.git] / client / src / views / Game.vue
index a2afb09..c3f2119 100644 (file)
@@ -236,7 +236,8 @@ export default {
       // If newmove got no pingback, send again:
       opponentGotMove: false,
       connexionString: "",
-      socketCloseListener: 0,
+      reopenTimeout: 0,
+      reconnectTimeout: 0,
       // Incomplete info games: show move played
       moveNotation: "",
       // Intervals from setInterval():
@@ -289,14 +290,13 @@ export default {
   },
   methods: {
     cleanBeforeDestroy: function() {
-      clearInterval(this.socketCloseListener);
       document.removeEventListener('visibilitychange', this.visibilityChange);
       window.removeEventListener('focus', this.onFocus);
       window.removeEventListener('blur', this.onBlur);
       if (!!this.askLastate) clearInterval(this.askLastate);
       if (!!this.retrySendmove) clearInterval(this.retrySendmove);
       if (!!this.clockUpdate) clearInterval(this.clockUpdate);
-      this.conn.removeEventListener("message", this.socketMessageListener);
+      clearTimeout(this.reopenTimeout);
       this.send("disconnect");
       this.conn = null;
     },
@@ -333,6 +333,29 @@ export default {
         )
       );
     },
+    requestLastate: function(sid) {
+      // TODO: maybe also find opponent SID ?
+      //const oppSid =
+      //  this.game.players.find(p => p.sid != this.st.user.sid).sid;
+      this.send("asklastate", { target: sid });
+      let counter = 1;
+      this.askLastate = setInterval(
+        () => {
+          // Ask at most 3 times:
+          // if no reply after that there should be a network issue.
+          if (
+            counter < 3 &&
+            !this.gotLastate &&
+            !!this.people[sid]
+          ) {
+            this.send("asklastate", { target: sid });
+            counter++;
+          }
+          else clearInterval(this.askLastate);
+        },
+        1500
+      );
+    },
     atCreation: function() {
       document.addEventListener('visibilitychange', this.visibilityChange);
       window.addEventListener('focus', this.onFocus);
@@ -351,7 +374,7 @@ export default {
           id: my.id,
           name: my.name,
           tmpIds: {
-            tmpId: { focus: true }
+            [tmpId]: { focus: true }
           }
         }
       );
@@ -386,28 +409,41 @@ export default {
         "&page=" +
         // Discard potential "/?next=[...]" for page indication:
         encodeURIComponent(this.$route.path.match(/\/game\/[a-zA-Z0-9]+/)[0]);
+      openConnection();
+    },
+    openConnection: function() {
       this.conn = new WebSocket(this.connexionString);
-      this.conn.addEventListener("message", this.socketMessageListener);
-      this.socketCloseListener = setInterval(
-        () => {
-          if (this.conn.readyState == 3) {
-            this.conn.removeEventListener(
-              "message", this.socketMessageListener);
-            this.conn = new WebSocket(this.connexionString);
-            this.conn.addEventListener("message", this.socketMessageListener);
-          }
-        },
-        1000
-      );
+      const onOpen = () => {
+        this.reconnectTimeout = 250;
+        const oppSid = this.getOppsid();
+        if (!!oppSid) this.requestLastate(oppSid); //in case of
+      };
+      this.conn.onopen = onOpen;
+      this.conn.onmessage = this.socketMessageListener;
+      const closeConnection = () => {
+        this.reopenTimeout = setTimeout(
+          () => {
+            this.openConnection();
+            this.reconnectTimeout = Math.min(2*this.reconnectTimeout, 30000);
+          },
+          this.reconnectTimeout
+        );
+      };
+      this.conn.onerror = closeConnection;
+      this.conn.onclose = closeConnection;
       // Socket init required before loading remote game:
       const socketInit = callback => {
         if (this.conn.readyState == 1)
           // 1 == OPEN state
           callback();
-        else
+        else {
           // Socket not ready yet (initial loading)
           // NOTE: first arg is Websocket object, unused here:
-          this.conn.onopen = () => callback();
+          this.conn.onopen = () => {
+            onOpen();
+            callback();
+          };
+        }
       };
       this.fetchGame((game) => {
         if (!!game) {
@@ -672,24 +708,7 @@ export default {
             this.game.type == "live" &&
             this.game.players.some(p => p.sid == user.sid)
           ) {
-            this.send("asklastate", { target: user.sid });
-            let counter = 1;
-            this.askLastate = setInterval(
-              () => {
-                // Ask at most 3 times:
-                // if no reply after that there should be a network issue.
-                if (
-                  counter < 3 &&
-                  !this.gotLastate &&
-                  !!this.people[user.sid]
-                ) {
-                  this.send("asklastate", { target: user.sid });
-                  counter++;
-                }
-                else clearInterval(this.askLastate);
-              },
-              1500
-            );
+            this.requestLastate(user.sid);
           }
           break;
         }
@@ -1058,7 +1077,7 @@ export default {
         let gameInfo = {
           id: getRandString(), //ignored if corr
           fen: V.GenRandInitFen(this.game.options),
-          options: this.game.options,
+          options: JSON.stringify(this.game.options),
           players: [this.game.players[1], this.game.players[0]],
           vid: this.game.vid,
           cadence: this.game.cadence
@@ -1091,11 +1110,7 @@ export default {
             "/games",
             "POST",
             {
-              data: Object.assign(
-                {},
-                gameInfo,
-                { options: JSON.stringify(this.game.options) }
-              ),
+              data: { gameInfo: gameInfo },
               success: (response) => {
                 gameInfo.id = response.id;
                 notifyNewGame();
@@ -1312,7 +1327,9 @@ export default {
       const trySetVname = setInterval(
         () => {
           // this.st.variants might be uninitialized (variant == null)
-          variant = this.st.variants.find(v => v.id == game.vid);
+          variant = this.st.variants.find(v => {
+            return v.id == game.vid || v.name == game.vname
+          });
           if (!!variant) {
             clearInterval(trySetVname);
             game.vname = variant.name;
@@ -1612,7 +1629,9 @@ export default {
         if (["all","byrow"].includes(V.ShowMoves)) {
           this.curDiag = getDiagram({
             position: position,
-            orientation: V.CanFlip ? this.game.mycolor : "w"
+            orientation: V.CanFlip ? this.game.mycolor : "w",
+            color: this.game.mycolor,
+            score: "*"
           });
           document.querySelector("#confirmDiv > .card").style.width =
             boardDiv.offsetWidth + "px";