feat: entrée serveur (Hono + WebSocket /api/ws + worker)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
// server/index.ts
|
||||
import { serve } from "@hono/node-server";
|
||||
import { Hono } from "hono";
|
||||
import { WebSocketServer } from "ws";
|
||||
import type { IncomingMessage } from "node:http";
|
||||
import type { Duplex } from "node:stream";
|
||||
import { env } from "./env.js";
|
||||
import { runMigrations } from "./db/migrate.js";
|
||||
import { api } from "./routes/index.js";
|
||||
import { outputHub } from "./ws/outputHub.js";
|
||||
import { startWorker } from "./jobs/worker.js";
|
||||
|
||||
env.requireMasterKey();
|
||||
runMigrations();
|
||||
|
||||
const app = new Hono();
|
||||
app.route("/api", api);
|
||||
app.get("/health", (c) => c.json({ ok: true }));
|
||||
|
||||
const server = serve({ fetch: app.fetch, port: env.port }, (info) =>
|
||||
console.log(`[server] http://localhost:${info.port}`),
|
||||
);
|
||||
|
||||
// WebSocket: /api/ws/machines/:id/output
|
||||
const wss = new WebSocketServer({ noServer: true });
|
||||
server.on("upgrade", (req: IncomingMessage, socket: Duplex, head: Buffer) => {
|
||||
const match = /^\/api\/ws\/machines\/([^/]+)\/output$/.exec(req.url ?? "");
|
||||
if (!match) {
|
||||
socket.destroy();
|
||||
return;
|
||||
}
|
||||
const machineId = match[1]!;
|
||||
wss.handleUpgrade(req, socket, head, (ws) => {
|
||||
const unsub = outputHub.subscribe(machineId, (chunk) => {
|
||||
if (ws.readyState === ws.OPEN) ws.send(chunk);
|
||||
});
|
||||
ws.on("close", unsub);
|
||||
});
|
||||
});
|
||||
|
||||
startWorker();
|
||||
Reference in New Issue
Block a user