unregister interval prevent mem leak; don't reconnect on successfully websocket close

This commit is contained in:
evanpelle
2024-08-16 12:31:05 -07:00
parent 332c2cfcac
commit 0806ab17c5
4 changed files with 29 additions and 18 deletions
+3 -1
View File
@@ -20,8 +20,10 @@
* fix bug where game stops after 10s (websocket disconnection) DONE 8/16/2024
* fix server memory leak
* balance attacks/expansions better
* Bug: boats not going to destination, coast not being recognized
* BUG: boats not going to destination, coast not being recognized
* BUG: boats freeze game on path calculation
* double attack add troops
* Create separate game config dev vs prod
* Have some time for spawning before game starts
* delete players when territories too small
* better algorithm for name render placement
+6 -3
View File
@@ -76,7 +76,9 @@ export class ClientGame {
const message: ServerMessage = ServerMessageSchema.parse(JSON.parse(event.data))
if (message.type == "start") {
console.log("starting game!")
this.start()
if (!this.isActive) {
this.start()
}
}
if (message.type == "turn") {
this.addTurn(message.turn)
@@ -88,14 +90,15 @@ export class ClientGame {
};
this.socket.onclose = (event: CloseEvent) => {
console.log(`WebSocket closed. Code: ${event.code}, Reason: ${event.reason}`);
this.join()
if (event.code != 1000) {
this.join()
}
};
}
public start() {
this.isActive = true
console.log('starting game!')
// TODO: make each class do this, or maybe have client intercept all requests?
//this.eventBus.on(TickEvent, (e) => this.tick(e))
this.eventBus.on(TileEvent, (e) => this.renderer.tileUpdate(e))
-1
View File
@@ -38,7 +38,6 @@ export class GameManager {
if (now > this.lastNewLobby + this.config.gameCreationRate()) {
this.lastNewLobby = now
const id = this.random.nextID()
console.log(`creating game ${id}`)
lobbies.push(new GameServer(id, now, this.config))
}
+20 -13
View File
@@ -1,6 +1,8 @@
import {ClientMessage, ClientMessageSchema, Intent, ServerStartGameMessage, ServerStartGameMessageSchema, ServerTurnMessageSchema, Turn} from "../core/Schemas";
import {Config} from "../core/configuration/Config";
import {Client} from "./Client";
import WebSocket from 'ws';
export enum GamePhase {
Lobby = 'LOBBY',
@@ -18,6 +20,8 @@ export class GameServer {
private clients: Client[] = []
private _hasStarted = false
private endTurnIntervalID
constructor(
public readonly id: string,
public readonly createdAt: number,
@@ -39,32 +43,34 @@ export class GameServer {
}
}
})
// In case a client joined the game late and missed the start message.
if (this._hasStarted) {
this.sendStartGameMsg(client.ws)
}
}
public start() {
this._hasStarted = true
const startGame = JSON.stringify(ServerStartGameMessageSchema.parse(
{
type: "start"
}
))
this.clients.forEach(c => {
console.log(`game ${this.id} sending start message to ${c.id}`)
c.ws.send(startGame)
this.sendStartGameMsg(c.ws)
})
setInterval(() => this.endTurn(), this.settings.turnIntervalMs());
// setInterval(() => {
// this.clients.forEach(c => {
// c.ws.close(1011, 'Intentional error for testing');
// })
// }, 1000)
this.endTurnIntervalID = setInterval(() => this.endTurn(), this.settings.turnIntervalMs());
}
private addIntent(intent: Intent) {
this.intents.push(intent)
}
private sendStartGameMsg(ws: WebSocket) {
ws.send(JSON.stringify(ServerStartGameMessageSchema.parse(
{
type: "start"
}
)))
}
private endTurn() {
const pastTurn: Turn = {
turnNumber: this.turns.length,
@@ -88,6 +94,7 @@ export class GameServer {
endGame() {
// Close all WebSocket connections
clearInterval(this.endTurnIntervalID);
this.clients.forEach(client => {
client.ws.removeAllListeners('message');
if (client.ws.readyState === WebSocket.OPEN) {