// src/app/api/queue/events/route.ts import { NextRequest } from "next/server"; import { Redis } from "@/lib/Redis"; // 사용 중인 Redis 클라이언트 // 이 API는 캐시되지 않고 항상 실시간으로 작동해야 합니다. export const dynamic = "force-dynamic"; export async function GET(req: NextRequest) { // 프론트엔드에서 보낸 serverId 가져오기 const serverId = req.nextUrl.searchParams.get("serverId"); if (!serverId) { return new Response("Missing serverId", { status: 400 }); } // SSE(Server-Sent Events) 스트림 생성 const stream = new ReadableStream({ async start(controller) { // 🚨 중요: 구독(Subscribe) 전용으로 쓸 독립적인 Redis 연결을 하나 복제합니다. const subscriber = Redis.duplicate(); // 'bot-site' 채널 구독 await subscriber.subscribe("bot-site"); // 메세지가 들어올 때마다 실행 subscriber.on("message", (channel, message) => { if (channel !== "bot-site") return; const data = JSON.parse(message); if (data.guildId !== serverId) return; // 알림이 울린 서버와 현재 유저가 보고 있는 서버가 일치할 때만! if (data.event === "player_update") { // 프론트엔드로 "새로고침해!" 라는 데이터를 전송 controller.enqueue(`data: ${JSON.stringify({ type: "player_update" })}\n\n`); } }); // 클라이언트(웹사이트)가 브라우저를 닫거나 다른 페이지로 가면 연결 종료 및 정리 req.signal.addEventListener("abort", () => { subscriber.unsubscribe("bot-site"); subscriber.quit(); controller.close(); }); } }); // 스트림 응답 헤더 설정 (연결을 끊지 않고 계속 유지) return new Response(stream, { headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", "Connection": "keep-alive", }, }); }