mirror of
https://github.com/fccview/cronmaster.git
synced 2026-03-23 00:02:43 +08:00
73 lines
2.0 KiB
TypeScript
73 lines
2.0 KiB
TypeScript
import { NextRequest } from "next/server";
|
|
import { sseBroadcaster } from "@/app/_utils/sse-broadcaster";
|
|
import { createHeartbeatEvent } from "@/app/_utils/sse-events";
|
|
import { startLogWatcher } from "@/app/_utils/log-watcher";
|
|
import { requireAuth } from "@/app/_utils/api-auth-utils";
|
|
|
|
export const dynamic = "force-dynamic";
|
|
export const runtime = "nodejs";
|
|
|
|
let watcherStarted = false;
|
|
|
|
export const GET = async (request: NextRequest) => {
|
|
const authError = await requireAuth(request);
|
|
if (authError) return authError;
|
|
|
|
const liveUpdatesEnabled = process.env.LIVE_UPDATES !== "false";
|
|
|
|
if (!liveUpdatesEnabled) {
|
|
return new Response(
|
|
JSON.stringify({ error: "Live updates are disabled" }),
|
|
{
|
|
status: 503,
|
|
headers: { "Content-Type": "application/json" },
|
|
}
|
|
);
|
|
}
|
|
|
|
if (!watcherStarted) {
|
|
startLogWatcher();
|
|
watcherStarted = true;
|
|
}
|
|
|
|
const clientId = `client-${Date.now()}-${Math.random()
|
|
.toString(36)
|
|
.substring(7)}`;
|
|
|
|
const stream = new ReadableStream({
|
|
start(controller) {
|
|
sseBroadcaster.addClient(clientId, controller);
|
|
|
|
const encoder = new TextEncoder();
|
|
const welcome = encoder.encode(
|
|
`: Connected to Cronmaster SSE\nretry: 5000\n\n`
|
|
);
|
|
controller.enqueue(welcome);
|
|
|
|
const heartbeatInterval = setInterval(() => {
|
|
try {
|
|
const heartbeat = createHeartbeatEvent();
|
|
sseBroadcaster.sendToClient(clientId, heartbeat);
|
|
} catch (error) {
|
|
console.error("[SSE] Heartbeat error:", error);
|
|
clearInterval(heartbeatInterval);
|
|
}
|
|
}, 30000);
|
|
|
|
request.signal.addEventListener("abort", () => {
|
|
clearInterval(heartbeatInterval);
|
|
sseBroadcaster.removeClient(clientId);
|
|
});
|
|
},
|
|
});
|
|
|
|
return new Response(stream, {
|
|
headers: {
|
|
"Content-Type": "text/event-stream",
|
|
"Cache-Control": "no-cache, no-transform",
|
|
Connection: "keep-alive",
|
|
"X-Accel-Buffering": "no",
|
|
},
|
|
});
|
|
};
|