Show the players

Send keepalive pings. Remove players who haven't sent pings.
This commit is contained in:
jude 2023-01-14 16:59:11 +00:00
parent 39c31e0f90
commit 8e22d37b64
4 changed files with 44 additions and 4 deletions

3
app.py
View File

@ -12,9 +12,8 @@ def index():
@socketio.event @socketio.event
def message(data): def message(data):
print(data)
emit('message', data, broadcast=True) emit('message', data, broadcast=True)
if __name__ == '__main__': if __name__ == '__main__':
socketio.run(app, log_output=True) socketio.run(app, log_output=True, debug=True)

View File

@ -0,0 +1,6 @@
#players {
position: absolute;
right: 0;
top: 0;
padding: 12px;
}

View File

@ -1,4 +1,6 @@
const ID = window.crypto.randomUUID(); const ID = window.crypto.randomUUID();
// Timeout to consider a player disconnected
const TIMEOUT = 30_000;
let players = {}; let players = {};
@ -8,7 +10,7 @@ document.addEventListener("DOMContentLoaded", () => {
socket.on("connect", () => { socket.on("connect", () => {
console.log("Connected!"); console.log("Connected!");
socket.emit("message", { type: "ANNOUNCE", author: ID, name: "" }); socket.emit("message", { type: "ANNOUNCE", author: ID, name: "" });
players[ID] = { name: "" }; players[ID] = { name: "", timeout: null };
}); });
socket.on("message", (data) => { socket.on("message", (data) => {
@ -18,16 +20,42 @@ document.addEventListener("DOMContentLoaded", () => {
case "ANNOUNCE": case "ANNOUNCE":
playerConnected(socket, data); playerConnected(socket, data);
break; 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) { function playerConnected(socket, data) {
// When a new player is seen, all announce to ensure they know all players. // When a new player is seen, all announce to ensure they know all players.
if (players[data.author] === undefined) { 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: "" }); socket.emit("message", { type: "ANNOUNCE", author: ID, name: "" });
} else { } 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);
}
} }

View File

@ -9,5 +9,12 @@
<script src="{{ url_for('static', filename='js/index.js') }}"></script> <script src="{{ url_for('static', filename='js/index.js') }}"></script>
</head> </head>
<body> <body>
<div id="players">
<strong>Players</strong>
<ul id="playerList">
</ul>
</div>
</body> </body>
</html> </html>