react 流式输出
时间: 2025-02-04 18:06:09 浏览: 48
实现 React 中的流式输出
为了实现在 React 组件中的流式输出,通常会利用 WebSockets 或者 Server-Sent Events (SSE),这些技术允许服务器向客户端推送数据更新而不需要客户端发起新的请求。对于更现代的方法,在某些情况下也可以考虑使用 Fetch API 结合 ReadableStream
接口。
当涉及到具体的实现细节时,如果目标是在前端展示来自后端服务的数据流,则可以采取以下方式之一:
使用 SSE 进行流式传输
Server-sent events 是一种简单的方式让服务器能够主动发送消息给浏览器。下面是一个简单的例子说明如何设置一个 React 应用来接收并处理通过 SSE 发送的消息。
import { useEffect, useState } from 'react';
function StreamOutputComponent() {
const [messages, setMessages] = useState([]);
useEffect(() => {
let eventSource;
try {
eventSource = new EventSource('/stream-endpoint');
eventSource.onmessage = function(event) {
setMessages(prevMessages => [...prevMessages, JSON.parse(event.data)]);
};
return () => {
if (eventSource && eventSource.readyState === 1 /* OPEN */) {
eventSource.close();
}
};
} catch (error) {
console.error('Error establishing connection to stream endpoint.', error);
}
// Cleanup on unmount or update
return () => {
if (eventSource?.readyState !== 2 /* CLOSED */) {
eventSource.close();
}
};
}, []);
return (
<div>
<h3>实时日志</h3>
<ul>
{messages.map((msg, index) =>
<li key={index}>{JSON.stringify(msg)}</li>)}
</ul>
</div>
);
}
export default StreamOutputComponent;
此组件会在挂载时建立与 /stream-endpoint
的连接,并监听传入的消息事件。每当收到新消息时都会将其添加到状态列表中以便渲染出来[^1]。
利用 WebSocket 实现实时通信
WebSockets 提供了一种全双工通道用于双向通讯。这非常适合那些不仅需要从服务器接收入站通知的应用场景,同时也可能想要发送指令回服务器的情况。
import { useEffect, useRef, useState } from 'react';
import io from 'socket.io-client';
const socketUrl = process.env.REACT_APP_SOCKET_URL || "ws://localhost:4000";
function ChatApp() {
const wsRef = useRef(null);
const [chatHistory, setChatHistory] = useState([]);
useEffect(() => {
wsRef.current = io(socketUrl);
wsRef.current.on('connect', () => {
console.log(`Connected to ${socketUrl}`);
});
wsRef.current.on('newMessageToClient', message => {
setChatHistory([...chatHistory, message]);
});
return () => {
wsRef.current.disconnect();
};
}, []);
return (
<>
{/* Render chat history and input form here */}
</>
);
}
export default ChatApp;
在这个例子中,我们创建了一个名为 ChatApp
的组件,它负责管理聊天记录的状态以及与WebSocket服务器之间的交互逻辑。
配置 Express.js 来支持 SSE 和 WebSocket
为了让上述两个方案工作正常,还需要配置好相应的后端环境。这里以 Node.js + Express为例介绍怎样快速搭建起这两个协议的支持。
设置 SSE 路由
// server/index.js
const express = require('express');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 5000;
app.get('/stream-endpoint', async(req, res) => {
req.setTimeout(Infinity);
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
setInterval(() => {
res.write(`data: {"time": "${Date.now()}"}\n\n`);
}, 1000 * 5); // Send time every five seconds.
});
app.listen(PORT, () => {
console.log(`Listening at http://localhost:${PORT}/`);
});
添加 WebSocket 支持
// server/index.js continued...
const http = require('http');
const { Server } = require('socket.io');
const server = http.createServer(app);
const io = new Server(server);
io.on('connection', clientSocket => {
console.log('New Client Connected!');
clientSocket.emit('welcome', 'Welcome To The Chat Room!');
clientSocket.on('disconnect', reason => {
console.log(reason);
});
clientSocket.on('sendMessageFromClient', data => {
io.sockets.emit('newMessageToClient', `${clientSocket.id}: ${data.message}`);
});
});
server.listen(process.env.WEBSOCKET_PORT || 4000, () => {
console.log(`WebSocket listening on port ${process.env.WEBSOCKET_PORT || 4000}.`);
});
以上代码片段展示了如何在Express应用里增加对这两种不同类型的流媒体的支持。
相关推荐


















