Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions gateway/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# ---- Gateway Dockerfile ----
# Uses Bun to run TypeScript directly (no build step needed)
FROM oven/bun:1-alpine AS base

WORKDIR /app

# Install dependencies
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile --production

# Copy source
COPY . .

ENV PORT=3000
EXPOSE 3000

CMD ["bun", "run", "index.ts"]
9 changes: 9 additions & 0 deletions gateway/helper/generateRoom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const generateRoom = () => {
const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
let code = "";
for (let i = 0; i < 5; i++)
code += chars[Math.floor(Math.random() * chars.length)];
return code;
};

export default generateRoom;
19 changes: 8 additions & 11 deletions gateway/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
import createRoom from "./routes/createRoom";
import express from "express";
import addToRoom from "./routes/addToRoom";
import { createClient } from "redis";

const redisURL: string = process.env.REDIS_URL!;
const client = createClient({ url: redisURL });
try {
await client.connect();
} catch (e) {
console.error(e);
process.exit(1);
}
const app = express();
app.use(express.json());
const port = process.env.PORT || 3000;
let roomMaps: { [id: string]: { [id: string]: string | number } } = {};

app.post("/add", addToRoom);
// Kubernetes health probe
app.get("/healthz", (_, res) => res.status(200).send("ok"));
// Adds a client to a given room
app.get("/add", addToRoom);
// Allocates a room to a client
app.get("/createRoom", createRoom);

app.listen(port, () => {
console.log(`Listening on ${port}`);
});

export default client;
export default roomMaps;
25 changes: 14 additions & 11 deletions gateway/routes/addToRoom.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { type Request, type Response } from "express";
import client from "../index.ts";
import roomMaps from "../index.ts";
const addToRoom = async (req: Request, res: Response) => {
try {
const roomId = await client.get("key");
if (roomId == null) {
// Find a cool server that can handle it
await client.set("key", "value");
} else {
// Return the server ip in a cookie
}
} catch (e) {
console.error(e);
if (!req.body) {
res.status(400).send("No body");
return;
}
const roomId = req.body.roomId;
if (roomId == undefined || roomMaps[roomId] == undefined) {
res.status(400).send("Invalid room id");
return;
}

res.cookie("hostip", roomMaps[roomId]["hostIp"]);
res.cookie("port", roomMaps[roomId]["port"]);
res.status(200).send("here have your server");
return;
Comment on lines +4 to +17
};

export default addToRoom;
55 changes: 45 additions & 10 deletions gateway/routes/createRoom.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,49 @@
import { type Request, type Response } from "express";
import addToRoom from "./addToRoom";
const createRoom = async (req: Request, res: Response) => {
const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
let code = "";
for (let i = 0; i < 5; i++)
code += chars[Math.floor(Math.random() * chars.length)];

//TODO: Add check for room code in redis
req.cookies.roomId = code;
await addToRoom(req, res);
import generateRoom from "../helper/generateRoom";
import roomMaps from "../index.ts";
const createRoom = async (_: Request, res: Response) => {
let code: string;

// Generate a unqiue room code
do {
code = generateRoom();
} while (roomMaps[code] != undefined);

const serverManager = process.env.SERVER_MANAGER_URL;

try {
// Get assigned a server
const response = await fetch(`${serverManager}/assign`);

Comment on lines +12 to +17
// Validate response
if (
response.headers.get("hostip") == null ||
response.headers.get("port") == null
) {
res.status(400).send("Couldn't get servers");
return;
}

let roomInfo = {
hostIp: "",
port: 0,
};
roomInfo.hostIp = response.headers.get("hostip")!;
roomInfo.port = Number(response.headers.get("port"));

// Add roominfo in the map
// TODO: Instead of using a map, use a key value store like Redis
roomMaps[code] = roomInfo;

// Set cookies
res.cookie("hostIp", roomInfo.hostIp);
res.cookie("port", roomInfo.port);
res.cookie("roomID", code);
res.status(200).send("Here have your server");
} catch (e) {
console.error(e);
res.status(400).send("Bad request");
}
};

export default createRoom;
7 changes: 7 additions & 0 deletions gateway/types/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
interface Server {
hostIp: string;
port: number;
connections: number;
}

export type { Server };
Loading