generated at
Next.jsでのSSEの例

SSEの例




app/sample/route.ts
import { NextRequest, NextResponse } from 'next/server'; export async function GET(_req: NextRequest) { const stream = new TransformStream(); const writer = stream.writable.getWriter(); const encoder = new TextEncoder(); sendCharacters(text); return new NextResponse(stream.readable, { headers: { 'Content-Type': 'text/event-stream', }, }); async function sendCharacters(remainingText: string) { if (remainingText.length === 0) { writer.close(); return; } const c = remainingText.at(0); const rest = remainingText.slice(1); const message = encoder.encode(`data: ${c}\n\n`); await writer.write(message); await sleep(100); await sendCharacters(rest); } } const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); const text = '私はその人を常に先生と呼んでいた。だからここでもただ先生と書くだけで本名は打ち明けない。これは世間を憚る遠慮というよりも、その方が私にとって自然だからである。私はその人の記憶を呼び起こすごとに、すぐ「先生」といいたくなる。';

app/sample/SSE.ts
'use client'; import { useState, useEffect } from 'react'; export const Component = () => { const [message, setMessage] = useState(''); useEffect(() => { const eventSource = new EventSource('sample'); const handleEventSourceMessage = (event: MessageEvent) => { setMessage(p => `${p}${event.data}`); }; const handleEventSourceError = (error: Event) => { console.error('EventSource failed:', error); eventSource.close(); }; eventSource.addEventListener('message', handleEventSourceMessage); eventSource.addEventListener('error', handleEventSourceError); return () => { eventSource.removeEventListener('message', handleEventSourceMessage); eventSource.removeEventListener('error', handleEventSourceError); eventSource.close(); }; }, []); return <div className="w-full p-8">{message}</div>; };