思路:使用nodejs搭建服务端,接收到客户端发送的问题后返回加载响应,然后调用ai接口,等待ai接口响应后将响应结果通过sse推送给客户端;使用react搭建页面,主要由问题输入框、发送按钮和问答信息展示模块
步骤:
创建node项目,安装相关依赖项
npm init -y npm install express openai body-parser cors
创建
server.js
文件,配置服务const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const OpenAI = require("openai"); const app = express(); const port = 3001; app.use(cors()); app.use(bodyParser.json()); // deepseek 配置 // const openai = new OpenAI({ // baseURL: 'https://api.deepseek.com/v1', // apiKey: '你的key' // }); // 存储 SSE 客户端连接 const clients = new Map(); // SSE 端点 app.get('/stream', (req, res) => { const clientId = Date.now().toString(); res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); // 存储连接并发送客户端 ID clients.set(clientId, res); res.write(`event: clientId\ndata: ${clientId}\n\n`); // 心跳保持连接 const heartbeat = setInterval(() => res.write(': heartbeat\n\n'), 30000); req.on('close', () => { clearInterval(heartbeat); clients.delete(clientId); }); }); // 消息处理端点 app.post('/chat', async (req, res) => { const { clientId, message } = req.body; // 立即返回等待提示 res.status(200).send('AI 正在思考中...'); // 模拟 AI 接口调用 setTimeout(async () => { try { const aiResponse = `AI回复:${Math.random() * 100}`; // 替换为真实 AI 响应 const clientRes = clients.get(clientId); if (clientRes) { clientRes.write(`event: response\n`); clientRes.write(`data: ${JSON.stringify({ text: aiResponse })}\n\n`); } } catch (error) { const clientRes = clients.get(clientId); clientRes?.write(`event: error\ndata: ${error.message}\n\n`); } }, 2000); }); app.listen(port, () => { console.log(`Server is running on http://localhost:${port}`); });
搭建前端项目
npx create-react-app ai-chat cd ai-chat npm install axios
在
src
文件下,创建Chat.js
文件,搭建简单聊天页面import React, { useState, useEffect } from 'react'; import axios from 'axios'; function Chat() { const [messages, setMessages] = useState([]); const [input, setInput] = useState(''); const [clientId, setClientId] = useState(null); useEffect(() => { const es = new EventSource('http://localhost:3001/stream'); es.addEventListener('clientId', (e) => { setClientId(e.data); }); es.addEventListener('response', (e) => { const data = JSON.parse(e.data); setMessages(prev => [...prev, { text: data.text, type: 'Ai' }]); }); es.addEventListener('error', (e) => { console.error('SSE Error:', e.data); }); return () => { es.close(); }; }, []); const sendMessage = async () => { if (!input || !clientId) return; // 添加用户消息 setMessages(prev => [...prev, { text: input, type: 'user' }]); try { const response = await axios.post('http://localhost:3001/chat', { clientId: clientId, message: input }, { headers: { 'Content-Type': 'application/json', }, }); console.log('Server response:', response.data); // 假设服务器返回的消息格式为 setMessages(prev => [...prev, { text: response.data, type: 'Ai' }]); console.log('Messages:', messages); setInput(''); } catch (error) { console.error('Error while sending message:', error); } }; return ( <div> <input type="text" value={input} onChange={(e) => setInput(e.target.value)} placeholder="输入你的消息..." /> <button onClick={sendMessage}>发送</button> <div> {messages.map((message, index) => ( <div key={index}>{message.type}: {message.text}</div> ))} </div> </div> ); } export default Chat;
修改
App.js
文件,引入搭建好的聊天页面import './App.css'; import Chat from './Chat'; function App() { return ( <div className="App"> <Chat /> </div> ); } export default App;
在
server.js
同级目录下,启动服务node server.js
在
ai-chat
文件夹下,启动前端项目npm start
- 在浏览器中访问:http://localhost:3000 即可看到简单的聊天界面,发送消息后能收到服务端使用sse推送的消息,替换为真实的ai请求即可与AI聊天
1 条评论
?幽默类评语?