diff options
author | Thomas Voss <thomasvoss@live.com> | 2022-01-09 23:47:35 +0100 |
---|---|---|
committer | Thomas Voss <thomasvoss@live.com> | 2022-01-09 23:47:35 +0100 |
commit | 9757707f06fbec379e6d8e940cc9d7919480c7c7 (patch) | |
tree | d8fdb2e6c7491c4e36177c206a3f348fd8c63672 | |
parent | fc39c5256e9366d417a64ec4a3554eab5c84c64b (diff) |
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.
-rw-r--r-- | draughts/app.js | 59 |
1 files 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) |