typescript server.ts
This commit is contained in:
+4
-3
@@ -3,9 +3,10 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "node server.mjs",
|
"dev": "npm run buildserver && node ./.next/server.js",
|
||||||
"build": "next build",
|
"build": "npm run buildserver && next build",
|
||||||
"start": "NODE_ENV=production node server.mjs"
|
"start": "npm run buildserver && NODE_ENV=production node ./.next/server.js",
|
||||||
|
"buildserver": "tsc -p server.tsconfig.json"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/lang-go": "^6.0.1",
|
"@codemirror/lang-go": "^6.0.1",
|
||||||
|
|||||||
+4
-4
@@ -11,7 +11,7 @@ app.prepare().then(() => {
|
|||||||
handle(req, res);
|
handle(req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
const clients = {};
|
const runs = {};
|
||||||
|
|
||||||
const wss = new WebSocketServer({ noServer: true });
|
const wss = new WebSocketServer({ noServer: true });
|
||||||
|
|
||||||
@@ -19,8 +19,8 @@ app.prepare().then(() => {
|
|||||||
wss.on('connection', (ws, req) => {
|
wss.on('connection', (ws, req) => {
|
||||||
ws.on('message', (msg) => {
|
ws.on('message', (msg) => {
|
||||||
const runId = msg.toString();
|
const runId = msg.toString();
|
||||||
if (!clients[runId]) clients[runId] = []
|
if (!runs[runId]) runs[runId] = { clients: [] }
|
||||||
clients[runId].push(ws);
|
runs[runId].clients.push(ws);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ app.prepare().then(() => {
|
|||||||
req.on('end', () => {
|
req.on('end', () => {
|
||||||
const move = JSON.parse(body);
|
const move = JSON.parse(body);
|
||||||
|
|
||||||
clients[move.runId]?.forEach(client => {
|
runs[move.runId]?.clients.forEach(client => {
|
||||||
if (client.readyState === client.OPEN) {
|
if (client.readyState === client.OPEN) {
|
||||||
client.send(JSON.stringify(move.moves));
|
client.send(JSON.stringify(move.moves));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
import { createServer, IncomingMessage } from "http";
|
||||||
|
import next from "next";
|
||||||
|
import { WebSocketServer, WebSocket } from "ws";
|
||||||
|
|
||||||
|
const dev = process.env.NODE_ENV !== "production";
|
||||||
|
const app = next({ dev });
|
||||||
|
const handle = app.getRequestHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One run = many websocket clients
|
||||||
|
*/
|
||||||
|
type LiveRun = {
|
||||||
|
clients: Set<WebSocket>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const runs: Record<string, LiveRun> = {};
|
||||||
|
|
||||||
|
app.prepare().then(() => {
|
||||||
|
const server = createServer((req, res) => {
|
||||||
|
handle(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
const wss = new WebSocketServer({ noServer: true });
|
||||||
|
|
||||||
|
// WebSocket connections
|
||||||
|
wss.on("connection", (ws: WebSocket, req: IncomingMessage) => {
|
||||||
|
ws.on("message", (msg: Buffer) => {
|
||||||
|
const runId = msg.toString();
|
||||||
|
|
||||||
|
if (!runs[runId]) {
|
||||||
|
runs[runId] = { clients: new Set() };
|
||||||
|
}
|
||||||
|
|
||||||
|
runs[runId].clients.add(ws);
|
||||||
|
|
||||||
|
ws.once("close", () => {
|
||||||
|
runs[runId]?.clients.delete(ws);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle POST requests
|
||||||
|
server.on("request", (req, res) => {
|
||||||
|
if (req.method === "POST" && req.url === "/api/run/move") {
|
||||||
|
let body = "";
|
||||||
|
|
||||||
|
req.on("data", (chunk: Buffer) => {
|
||||||
|
body += chunk.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on("end", () => {
|
||||||
|
try {
|
||||||
|
const move: {
|
||||||
|
runId: string;
|
||||||
|
moves: unknown;
|
||||||
|
} = JSON.parse(body);
|
||||||
|
|
||||||
|
runs[move.runId]?.clients.forEach((client) => {
|
||||||
|
if (client.readyState === WebSocket.OPEN) {
|
||||||
|
client.send(JSON.stringify(move.moves));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res.writeHead(200, { "Content-Type": "application/json" });
|
||||||
|
res.end(JSON.stringify({ status: "ok" }));
|
||||||
|
} catch (err) {
|
||||||
|
res.writeHead(400);
|
||||||
|
res.end("Invalid JSON");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Upgrade HTTP → WebSocket
|
||||||
|
server.on("upgrade", (req, socket, head) => {
|
||||||
|
if (req.url === "/api/view-run") {
|
||||||
|
wss.handleUpgrade(req, socket, head, (ws) => {
|
||||||
|
wss.emit("connection", ws, req);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(3000, () => {
|
||||||
|
console.log("Server running on http://localhost:3000");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"noEmit": false,
|
||||||
|
"outDir": "./.next",
|
||||||
|
"target": "ES2020",
|
||||||
|
"module": "NodeNext",
|
||||||
|
"moduleResolution": "NodeNext",
|
||||||
|
"lib": ["ES2020"],
|
||||||
|
"types": ["node"],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"incremental": false,
|
||||||
|
"composite": false
|
||||||
|
},
|
||||||
|
"include": ["server.ts"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user