From 9757707f06fbec379e6d8e940cc9d7919480c7c7 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Sun, 9 Jan 2022 23:47:35 +0100 Subject: Add a game queue and handle disconnects The server now has an array of games that currently exist. When a client attempts to join a game, the server will check if another player is already waiting for an opponent and if so, matches the two players against each other. If all the games are full the server will create a new game and the player will need to wait for an opponent. The server also has handling for clients that disconnect. When that event occurs, the remaining client is sent a message informing them that their opponent disconnected, and the game is deleted. None of the statistics are updated as it wouldn't make sense to count a statistic such as `minimumMoves' if the opponent disconnected only a few moves in. --- draughts/app.js | 59 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/draughts/app.js b/draughts/app.js index 1e928f1..fea0287 100644 --- a/draughts/app.js +++ b/draughts/app.js @@ -1,12 +1,53 @@ -const express = require("express"); -const http = require("http"); -const indexRouter = require("./routes/index"); +const Http = require("http") +const WebSocket = require("ws") +const Express = require("express") -const port = process.argv[2]; -const app = express(); +const Game = require("./game") +const indexRouter = require("./routes/index") +const env = require("./environment") -app.get("/play", indexRouter); -app.get("/", indexRouter); +/* Get the server port, if the user doesn't provide one then print an error to STDERR and exit */ +const port = process.argv[2] +if (!port) { + process.stderr.write("Usage: npm start port") + process.exit(1) +} -app.use(express.static(__dirname + "/public")); -http.createServer(app).listen(port); +/* Initialize the routes */ +const app = Express() +app.get("/", indexRouter) +app.get("/play", indexRouter) +app.use(Express.static(__dirname + "/public")) + +/* Initialize the server and websocket server */ +const server = Http.createServer(app) +const wss = new WebSocket.Server({ server }) + +wss.on("connection", ws => { + /* When a new client connects, get the first game whos status is pending and add the client to + * that game. If there is no such game, then create a new one which will wait for a second client + * to join. + */ + let game = env.games.filter(g => g.ongoing)[0] + if (!game) { + game = new Game(env.games.length) /* The number of games servers as a unique game ID */ + env.games.push(game) + game.bluePlayer = ws + } else { + game.redPlayer = ws + game.messageAll("START") + } + + /* When a client disconnects, check if the game they were part of was ongoing (the game could + * have been waiting for a second client to join). If it was, message the opponent that they + * have won. Regardless of the state of the game, make sure to remove the game from the games + * array. + */ + ws.on("close", () => { + if (game.ongoing) + (ws == game.bluePlayer ? game.redPlayer : game.bluePlayer).send("DISCONNECT") + env.games = env.games.filter(g => g != game) + }) +}) + +server.listen(port) -- cgit v1.2.3