X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fviews%2FGame.vue;h=8c5e7c28af8eb0849d19d3f02e36516500c36bbd;hb=81b71035639a4204bd7834c9185ea961755af1cf;hp=a2afb09dc20295dcb59bd4888d3c243fb9126761;hpb=3d9745ae10ba867e4c1ec6e848db29c5e293420b;p=vchess.git diff --git a/client/src/views/Game.vue b/client/src/views/Game.vue index a2afb09d..8c5e7c28 100644 --- a/client/src/views/Game.vue +++ b/client/src/views/Game.vue @@ -231,17 +231,13 @@ export default { conn: null, roomInitialized: false, // If asklastate got no reply, ask again: - gotLastate: false, gotMoveIdx: -1, //last move index received - // If newmove got no pingback, send again: - opponentGotMove: false, + opponentGotMove: false, //used to freeze clock connexionString: "", - socketCloseListener: 0, - // Incomplete info games: show move played + reopenTimeout: 0, + reconnectTimeout: 0, + // Incomplete info games: show move played: moveNotation: "", - // Intervals from setInterval(): - askLastate: null, - retrySendmove: null, clockUpdate: null, // Related to (killing of) self multi-connects: newConnect: {} @@ -289,14 +285,11 @@ 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 +326,12 @@ 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 }); + }, atCreation: function() { document.addEventListener('visibilitychange', this.visibilityChange); window.addEventListener('focus', this.onFocus); @@ -351,7 +350,7 @@ export default { id: my.id, name: my.name, tmpIds: { - tmpId: { focus: true } + [tmpId]: { focus: true } } } ); @@ -370,11 +369,8 @@ export default { this.rematchOffer = ""; this.lastate = undefined; this.roomInitialized = false; - this.gotLastate = false; this.gotMoveIdx = -1; this.opponentGotMove = false; - this.askLastate = null; - this.retrySendmove = null; this.clockUpdate = null; this.newConnect = {}; // 1] Initialize connection @@ -386,28 +382,41 @@ export default { "&page=" + // Discard potential "/?next=[...]" for page indication: encodeURIComponent(this.$route.path.match(/\/game\/[a-zA-Z0-9]+/)[0]); + this.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.send("asklastate", { target: oppSid }); + }; + 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) { @@ -438,8 +447,13 @@ export default { } }, send: function(code, obj) { - if (!!this.conn && this.conn.readyState == 1) - this.conn.send(JSON.stringify(Object.assign({ code: code }, obj))); + let timeout = 0; + const trySend = () => { + if (!!this.conn && this.conn.readyState == 1) + this.conn.send(JSON.stringify(Object.assign({ code: code }, obj))); + else setTimeout(trySend, timeout = (timeout > 0 ? 2 * timeout : 250)); + } + setTimeout(trySend, timeout); }, isConnected: function(index) { const player = this.game.players[index]; @@ -667,29 +681,11 @@ export default { } // Ask potentially missed last state, if opponent and I play if ( - !this.gotLastate && !!this.game.mycolor && 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 - ); } break; } @@ -749,7 +745,6 @@ export default { // Confirm scenario? Fix? case "lastate": { // Got opponent infos about last move - this.gotLastate = true; this.lastate = data.data; if (this.lastate.movesCount - 1 > this.gotMoveIdx) this.gotMoveIdx = this.lastate.movesCount - 1; @@ -1058,7 +1053,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 +1086,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(); @@ -1309,10 +1300,13 @@ export default { ).replace(/(fen:)([^:]*):/g, replaceByDiag); }; let variant = undefined; + // TODO: avoid setInterval() here 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; @@ -1535,33 +1529,7 @@ export default { sendMove["clock"] = this.game.clocks[colorIdx]; // (Live) Clocks will re-start when the opponent pingback arrive this.opponentGotMove = false; - this.send("newmove", {data: sendMove}); - // If the opponent doesn't reply gotmove soon enough, re-send move: - // Do this at most 2 times, because more would mean network issues, - // opponent would then be expected to disconnect/reconnect. - let counter = 1; - const currentUrl = document.location.href; - this.retrySendmove = setInterval( - () => { - if ( - counter >= 3 || - this.opponentGotMove || - document.location.href != currentUrl //page change - ) { - clearInterval(this.retrySendmove); - return; - } - const oppsid = this.getOppsid(); - if (!oppsid) - // Opponent is disconnected: he'll ask last state - clearInterval(this.retrySendmove); - else { - this.send("newmove", { data: sendMove, target: oppsid }); - counter++; - } - }, - 1500 - ); + this.send("newmove", { data: sendMove }); } else // Not my move or I'm an observer: just start other player's clock @@ -1612,7 +1580,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";