Skip to content

Commit 4efa27a

Browse files
Allow specifying a webRoot in GameServer constructor
1 parent d5d8990 commit 4efa27a

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@code-game-project/server",
3-
"version": "0.3.0",
3+
"version": "0.4.0",
44
"description": "This is the JavaScript (and TypeScript) server library for CodeGame.",
55
"license": "MIT",
66
"author": {

src/api.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Router, json } from "express";
2+
import express from "express";
23
import { GameServer } from "./server.js";
34

45
export interface Info {
@@ -16,14 +17,23 @@ interface InfoInternal extends Info {
1617
/**
1718
* Creates an express.js `Router` that handles the standard routes defined in the Game Server Specification.
1819
* @param gameServer The `GameServer` instace.
20+
* @param webRoot The path to the root of the frontend. Specify `null` if there are no static assets.
1921
* @param cgePath The file path to the Code Game Events file about the game.
2022
* @param info Information about the game server.
2123
* @returns an express `Router`.
2224
*/
23-
export function createApi<Config extends object>(gameServer: GameServer<Config>, cgePath: string, info: InfoInternal): Router {
25+
export function createApi<Config extends object>(
26+
gameServer: GameServer<Config>,
27+
webRoot: string | null,
28+
cgePath: string,
29+
info: InfoInternal
30+
): Router {
2431
const router = Router();
2532
router.use(json({ limit: '2kb' }));
2633

34+
// static
35+
if (webRoot) router.use(express.static(webRoot));
36+
2737
// info
2838
router.get("/api/info", (_, res) => res.status(200).json(info));
2939

src/server.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,21 @@ export class GameServer<Config extends object = object> {
3636
private readonly privateGames: Games<Config> = {};
3737
public readonly logger = new Logger<Config>();
3838

39+
/**
40+
* Creates a new `GameServer`.
41+
* @param info Information about the game server.
42+
* @param cgePath The file path to the Code Game Events file about the game.
43+
* @param webRoot The path to the root of the frontend. Specify `null` if there are no static assets.
44+
* @param createGame A function that is called to create a new game. An instance of `Game` must be returned.
45+
* @param port The port that the server will bind to.
46+
* @param maxGamesCount The maximum number of games allowed on the server at once.
47+
* @param heartbeatIntervalSeconds The time in seconds to wait before checking again whether a socket is still alive.
48+
* @returns an instance of `GameServer`.
49+
*/
3950
public constructor(
4051
info: Info,
4152
cgePath: string,
53+
webroot: string | null,
4254
createGame: CreateGameFn<Config>,
4355
port: number = DEFAULT_PORT,
4456
maxGamesCount: number = DEFAULT_GAMES_COUNT,
@@ -54,7 +66,7 @@ export class GameServer<Config extends object = object> {
5466
// Api
5567
const app = express();
5668
app.use(cors());
57-
app.use(createApi(this, cgePath, Object.assign(info, { cg_version: CG_VERSION.join(".") })));
69+
app.use(createApi(this, webroot, cgePath, Object.assign(info, { cg_version: CG_VERSION.join(".") })));
5870

5971
// Game
6072
this.createGameFn = createGame;
@@ -70,6 +82,22 @@ export class GameServer<Config extends object = object> {
7082
this.HEARTBEAT_INTERVAL_SECONDS = heartbeatIntervalSeconds;
7183
}
7284

85+
/**
86+
* Stops the server from accepting new connections and keeps
87+
* existing connections. This function is asynchronous, the
88+
* server is finally closed when all connections are ended
89+
* and the server emits a 'close' event. The optional callback
90+
* will be called once the 'close' event occurs. Unlike that
91+
* event, it will be called with an Error as its only argument
92+
* if the server was not open when it was closed.
93+
*
94+
* See `http.Server.close` for more.
95+
*/
96+
public close(onCloseCallback?: ((err?: Error | undefined) => void) | undefined) {
97+
this.server.close(onCloseCallback);
98+
// TODO: Close all WebSockets if they are not already closed.
99+
}
100+
73101
/**
74102
* Looks for a game in the `publicGames`, as well as in the `privateGames`.
75103
* @param gameId The game ID.

0 commit comments

Comments
 (0)