diff options
Diffstat (limited to 'app/api/notifications/stream/route.ts')
| -rw-r--r-- | app/api/notifications/stream/route.ts | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/app/api/notifications/stream/route.ts b/app/api/notifications/stream/route.ts new file mode 100644 index 00000000..7ca6aab2 --- /dev/null +++ b/app/api/notifications/stream/route.ts @@ -0,0 +1,54 @@ +// app/api/notifications/stream/route.ts +import { NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; +import { authOptions } from "@/app/api/auth/[...nextauth]/route" +import realtimeNotificationService from '@/lib/realtime/RealtimeNotificationService'; + + +export async function GET(request: NextRequest) { + try { + const session = await getServerSession(authOptions); + if (!session?.user?.id) { + return new Response('Unauthorized', { status: 401 }); + } + + const userId = session.user.id; + const encoder = new TextEncoder(); + + const stream = new ReadableStream({ + start(controller) { + // 클라이언트 등록 + const clientId = realtimeNotificationService.addClient(userId, controller); + + console.log(`SSE stream started for user ${userId} (${clientId})`); + + // 초기 연결 확인 메시지 + controller.enqueue(encoder.encode("data: {\"type\":\"connected\"}\n\n")); + + // 연결 해제 처리 + request.signal.addEventListener('abort', () => { + console.log(`SSE stream ended for user ${userId} (${clientId})`); + realtimeNotificationService.removeClient(userId, controller); + controller.close(); + }); + }, + + cancel() { + console.log(`SSE stream cancelled for user ${userId}`); + realtimeNotificationService.removeClient(userId, controller); + } + }); + + return new Response(stream, { + headers: { + 'Content-Type': 'text/event-stream', + 'Cache-Control': 'no-cache, no-transform', + 'Connection': 'keep-alive', + 'X-Accel-Buffering': 'no', // Nginx 버퍼링 비활성화 + }, + }); + } catch (error) { + console.error('Error creating SSE stream:', error); + return new Response('Internal Server Error', { status: 500 }); + } + }
\ No newline at end of file |
