mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-06 17:56:47 +00:00
lobby websocket instead of polling (#2727)
## Description: Changes game lobbies into websockets instead of polling ## 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 ## Please put your Discord username so you can be contacted if a bug or regression is found: w.o.n --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: iamlewis <lewismmmm@gmail.com>
This commit is contained in:
+62
-5
@@ -5,6 +5,7 @@ import rateLimit from "express-rate-limit";
|
||||
import http from "http";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { WebSocket, WebSocketServer } from "ws";
|
||||
import { getServerConfigFromServer } from "../core/configuration/ConfigLoader";
|
||||
import { GameInfo } from "../core/Schemas";
|
||||
import { generateID } from "../core/Util";
|
||||
@@ -59,9 +60,32 @@ app.use(
|
||||
}),
|
||||
);
|
||||
|
||||
let publicLobbiesJsonStr = "";
|
||||
let publicLobbiesData: { lobbies: GameInfo[] } = { lobbies: [] };
|
||||
|
||||
const publicLobbyIDs: Set<string> = new Set();
|
||||
const connectedClients: Set<WebSocket> = new Set();
|
||||
|
||||
// Broadcast lobbies to all connected clients
|
||||
function broadcastLobbies() {
|
||||
const message = JSON.stringify({
|
||||
type: "lobbies_update",
|
||||
data: publicLobbiesData,
|
||||
});
|
||||
|
||||
const clientsToRemove: WebSocket[] = [];
|
||||
|
||||
connectedClients.forEach((client) => {
|
||||
if (client.readyState === WebSocket.OPEN) {
|
||||
client.send(message);
|
||||
} else {
|
||||
clientsToRemove.push(client);
|
||||
}
|
||||
});
|
||||
|
||||
clientsToRemove.forEach((client) => {
|
||||
connectedClients.delete(client);
|
||||
});
|
||||
}
|
||||
|
||||
// Start the master process
|
||||
export async function startMaster() {
|
||||
@@ -74,6 +98,37 @@ export async function startMaster() {
|
||||
log.info(`Primary ${process.pid} is running`);
|
||||
log.info(`Setting up ${config.numWorkers()} workers...`);
|
||||
|
||||
// Setup WebSocket server for clients
|
||||
const wss = new WebSocketServer({ server, path: "/lobbies" });
|
||||
|
||||
wss.on("connection", (ws: WebSocket) => {
|
||||
connectedClients.add(ws);
|
||||
|
||||
// Send current lobbies immediately (always send, even if empty)
|
||||
ws.send(
|
||||
JSON.stringify({ type: "lobbies_update", data: publicLobbiesData }),
|
||||
);
|
||||
|
||||
ws.on("close", () => {
|
||||
connectedClients.delete(ws);
|
||||
});
|
||||
|
||||
ws.on("error", (error) => {
|
||||
log.error(`WebSocket error:`, error);
|
||||
connectedClients.delete(ws);
|
||||
try {
|
||||
if (
|
||||
ws.readyState === WebSocket.OPEN ||
|
||||
ws.readyState === WebSocket.CONNECTING
|
||||
) {
|
||||
ws.close(1011, "WebSocket internal error");
|
||||
}
|
||||
} catch (closeError) {
|
||||
log.error("Error while closing WebSocket after error:", closeError);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Generate admin token for worker authentication
|
||||
const ADMIN_TOKEN = crypto.randomBytes(16).toString("hex");
|
||||
process.env.ADMIN_TOKEN = ADMIN_TOKEN;
|
||||
@@ -158,7 +213,7 @@ app.get("/api/env", async (req, res) => {
|
||||
|
||||
// Add lobbies endpoint to list public games for this worker
|
||||
app.get("/api/public_lobbies", async (req, res) => {
|
||||
res.send(publicLobbiesJsonStr);
|
||||
res.json(publicLobbiesData);
|
||||
});
|
||||
|
||||
async function fetchLobbies(): Promise<number> {
|
||||
@@ -225,10 +280,12 @@ async function fetchLobbies(): Promise<number> {
|
||||
}
|
||||
});
|
||||
|
||||
// Update the JSON string
|
||||
publicLobbiesJsonStr = JSON.stringify({
|
||||
// Update the lobbies data
|
||||
publicLobbiesData = {
|
||||
lobbies: lobbyInfos,
|
||||
});
|
||||
};
|
||||
|
||||
broadcastLobbies();
|
||||
|
||||
return publicLobbyIDs.size;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user