- 作者:老汪软件技巧
- 发表时间:2024-09-04 00:04
- 浏览量:
本文介绍了如何在 Next.js 中设置和实现服务器发送事件 (SSE) 以实现实时数据流。
1. 服务器端实现
首先,我们需要在服务器端创建一个 SSE 端点,以便客户端可以通过这个端点接收实时数据:
// app/api/sse/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
const encoder = new TextEncoder();
const readableStream = new ReadableStream({
start(controller) {
const intervalId = setInterval(() => {
// 检查流是否已关闭
if (controller.desiredSize === null) {
// 流已关闭,停止发送数据
clearInterval(intervalId);
return;
}
const data = JSON.stringify({ time: new Date().toISOString() });
try {
controller.enqueue(encoder.encode(`data: ${data}\n\n`)); // 推送数据
} catch (error) {
console.error('Error enqueueing data:', error);
clearInterval(intervalId);
}
}, 1000);
// 设置连接保持时间(可选)
const keepAlive = setTimeout(() => {
clearInterval(intervalId);
controller.close();
}, 30000); // 30 秒后自动关闭连接
// 使用 request.signal 监听客户端断开连接
request.signal.addEventListener('abort', () => {
clearInterval(intervalId);
clearTimeout(keepAlive);
controller.close();
});
},
});
return new NextResponse(readableStream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
},
});
}
2. 客户端实现
客户端需要使用 EventSource API 来接收从服务器推送的数据:
// app/page.tsx
'use client';
import * as React from 'react';
export default function Home() {
const [messages, setMessages] = React.useState<string[]>([]);
React.useEffect(() => {
const eventSource = new EventSource('/api/sse');
eventSource.onmessage = function (event) {
console.log("data",event)
const newMessage = JSON.parse(event.data);
setMessages((prevMessages) => [...prevMessages, newMessage.time]);
};
// 清除 EventSource 连接
return () => {
eventSource.close();
};
}, []);
return (
<div>
<h1>实时推送的消息:h1>
<ul>
{messages.map((message, index) => (
<li key={index}>{message}li>
))}
ul>
div>
);
}