mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-15 16:55:42 +00:00
Monitoring client connections (#941)
## Description: Disconnected client detection : If a client haven't send a ping to the server since more than 30 seconds They will then be marked disconnected with a dedicated icon. No action are yet taken, this allows for extensive in-game test before adding the *consequences* of the player leaving the game. I also added extensive unit tests, lessening the risk of regression for the future.  ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced - [x] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors ## Please put your Discord username so you can be contacted if a bug or regression is found: theodoreleon.aetarax --------- Co-authored-by: evanpelle <evanpelle@gmail.com>
This commit is contained in:
co-authored by
evanpelle
parent
02f7caef88
commit
a4fffce7f3
@@ -4,7 +4,8 @@ import { Tick } from "../core/game/Game";
|
||||
import { ClientID } from "../core/Schemas";
|
||||
|
||||
export class Client {
|
||||
public lastPing: number;
|
||||
public lastPing: number = Date.now();
|
||||
public isDisconnected: boolean = false;
|
||||
|
||||
public hashes: Map<Tick, number> = new Map();
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ export class GameServer {
|
||||
|
||||
private maxGameDuration = 3 * 60 * 60 * 1000; // 3 hours
|
||||
|
||||
private disconnectedTimeout = 1 * 30 * 1000; // 30 seconds
|
||||
|
||||
private turns: Turn[] = [];
|
||||
private intents: Intent[] = [];
|
||||
public activeClients: Client[] = [];
|
||||
@@ -164,6 +166,10 @@ export class GameServer {
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
client.isDisconnected = existing.isDisconnected;
|
||||
client.lastPing = existing.lastPing;
|
||||
|
||||
existing.ws.removeAllListeners("message");
|
||||
this.activeClients = this.activeClients.filter((c) => c !== existing);
|
||||
}
|
||||
@@ -195,6 +201,12 @@ export class GameServer {
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (clientMsg.intent.type === "mark_disconnected") {
|
||||
this.log.warn(
|
||||
`Should not receive mark_disconnected intent from client`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.addIntent(clientMsg.intent);
|
||||
}
|
||||
if (clientMsg.type === "ping") {
|
||||
@@ -357,6 +369,7 @@ export class GameServer {
|
||||
this.intents = [];
|
||||
|
||||
this.handleSynchronization();
|
||||
this.checkDisconnectedStatus();
|
||||
|
||||
let msg = "";
|
||||
try {
|
||||
@@ -537,6 +550,36 @@ export class GameServer {
|
||||
}
|
||||
}
|
||||
|
||||
private checkDisconnectedStatus() {
|
||||
if (this.turns.length % 5 !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const now = Date.now();
|
||||
for (const [clientID, client] of this.allClients) {
|
||||
if (
|
||||
client.isDisconnected === false &&
|
||||
now - client.lastPing > this.disconnectedTimeout
|
||||
) {
|
||||
this.markClientDisconnected(client, true);
|
||||
} else if (
|
||||
client.isDisconnected &&
|
||||
now - client.lastPing < this.disconnectedTimeout
|
||||
) {
|
||||
this.markClientDisconnected(client, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private markClientDisconnected(client: Client, isDisconnected: boolean) {
|
||||
client.isDisconnected = isDisconnected;
|
||||
this.addIntent({
|
||||
type: "mark_disconnected",
|
||||
clientID: client.clientID,
|
||||
isDisconnected: isDisconnected,
|
||||
});
|
||||
}
|
||||
|
||||
private archiveGame() {
|
||||
this.log.info("archiving game", {
|
||||
gameID: this.id,
|
||||
|
||||
Reference in New Issue
Block a user