Next.jsでのSSEの例
https://gyazo.com/4a74229987932b0cc8a48a7d9183b5b6
code: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 =
'私はその人を常に先生と呼んでいた。だからここでもただ先生と書くだけで本名は打ち明けない。これは世間を憚る遠慮というよりも、その方が私にとって自然だからである。私はその人の記憶を呼び起こすごとに、すぐ「先生」といいたくなる。';
code:app/sample/SSE.ts
'use client';
import { useState, useEffect } from 'react';
export const Component = () => {
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>;
};