NEXTJS SSEのサンプルコードです。
NextResponse でのサンプルコードがあまり見つからないので
- src/app/api/xxxの場合
サーバー側
import { NextRequest, NextResponse } from "next/server";
/*
sse通信のサンプルコード
*/
export async function GET(req:NextRequest) {
const stream = new TransformStream()
// 以下のwriterにメッセージを入れるとストリーミングメッセージとなる writer.write(message)
const writer = stream.writable.getWriter()
const encoder = new TextEncoder()
// 1秒後にファイルチェックの結果を流し込む 改行2個がデータエンドなので消さないこと。本文中の改行連続はエンコーダーで処理されており保存される
setTimeout(() => {
const message = encoder.encode(`data: ${JSON.stringify('File has been checked')}\n\n`);
writer.write(message);
console.log(message);
}, 1000);
// 2秒後にファイル解析の結果を流し込む
setTimeout(() => {
const message = encoder.encode(`data: ${JSON.stringify('File has been parsed')}\n\n`);
writer.write(message);
console.log(message);
}, 2000);
// 3秒後に接続を閉じる
setTimeout(() => {
writer.close();
console.log("finish")
}, 3000);
return new NextResponse(stream.readable, {
headers: {
'Content-Type': 'text/event-stream',
Connection: 'keep-alive',
'Cache-Control': 'no-cache, no-transform',
},
});
}
クライアント側
'use client'
import { useState, useEffect } from 'react';
/*
SSE通信のモデルコード
*/
const UploadComponent = () => {
const [status, setStatus] = useState<string>('');
useEffect(() => {
const handleEventSourceMessage = (event:any) => {
setStatus(JSON.parse(event.data));
};
const handleEventSourceError = () => {
eventSource.close(); // 接続が閉じられたら EventSource を明示的に閉じる
};
const eventSource = new EventSource('/api/sample/sse');
eventSource.addEventListener('message', handleEventSourceMessage);
eventSource.onerror = handleEventSourceError; // エラーハンドラを追加
return () => {
eventSource.removeEventListener('message', handleEventSourceMessage);
eventSource.close();
};
}, []);
const handleUpload = () => {
// TODO: 実際のアップロードロジック
// axios などを利用してファイルをサーバに POST
// 成功したら以下を実行
setStatus('File has been uploaded');
};
return (
<div>
<button onClick={handleUpload}>Upload File</button>
<p>Status: {status}</p>
</div>
);
};