diff --git a/app.py b/app.py index 9b480ce..88b1f2f 100644 --- a/app.py +++ b/app.py @@ -12,9 +12,8 @@ def index(): @socketio.event def message(data): - print(data) emit('message', data, broadcast=True) if __name__ == '__main__': - socketio.run(app, log_output=True) + socketio.run(app, log_output=True, debug=True) diff --git a/static/css/style.css b/static/css/style.css index e69de29..2e4884f 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -0,0 +1,6 @@ +#players { + position: absolute; + right: 0; + top: 0; + padding: 12px; +} diff --git a/static/js/index.js b/static/js/index.js index 107eaf4..28873c8 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -1,4 +1,6 @@ const ID = window.crypto.randomUUID(); +// Timeout to consider a player disconnected +const TIMEOUT = 30_000; let players = {}; @@ -8,7 +10,7 @@ document.addEventListener("DOMContentLoaded", () => { socket.on("connect", () => { console.log("Connected!"); socket.emit("message", { type: "ANNOUNCE", author: ID, name: "" }); - players[ID] = { name: "" }; + players[ID] = { name: "", timeout: null }; }); socket.on("message", (data) => { @@ -18,16 +20,42 @@ document.addEventListener("DOMContentLoaded", () => { case "ANNOUNCE": playerConnected(socket, data); break; + + case "KEEPALIVE": + keepAlive(data); + break; } } }); + + // Emit keepalive messages to inform other players we are still here + window.setInterval(() => { + socket.emit("message", { type: "KEEPALIVE", author: ID }); + }, TIMEOUT / 5); }); function playerConnected(socket, data) { // When a new player is seen, all announce to ensure they know all players. if (players[data.author] === undefined) { - players[data.author] = { name: data.name }; + players[data.author] = { name: data.name, timeout: window.setTimeout(() => { delete players[data.author]; updatePlayerDom(); }, TIMEOUT) }; socket.emit("message", { type: "ANNOUNCE", author: ID, name: "" }); } else { } + + updatePlayerDom(); +} + +function keepAlive(data) { + window.clearTimeout(players[data.author].timeout); + players[data.author].timeout = window.setTimeout(() => { delete players[data.author]; updatePlayerDom(); }, TIMEOUT); +} + +function updatePlayerDom() { + let list = document.querySelector('#playerList'); + list.replaceChildren(); + for (let playerId of Object.keys(players)) { + let newDom = document.createElement('li'); + newDom.textContent = playerId; + list.appendChild(newDom); + } } diff --git a/templates/index.html b/templates/index.html index 7a620b8..0c49a63 100644 --- a/templates/index.html +++ b/templates/index.html @@ -9,5 +9,12 @@
+ +