一、环境准备(详细步骤)
1.1 操作系统要求
- Windows 10/11 或 macOS 12+
- Linux(推荐 Ubuntu 22.04 LTS)
1.2 开发工具安装
bash
# 安装 Node.js(使用 Node 版本管理工具 nvm)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
source ~/.bashrc
nvm install 18.14.2
# 验证安装
node -v # 应输出 v18.14.2
npm -v # 应输出 9.5.0+
# 安装 Trae 核心 CLI
npm install -g @traejs/[email protected] --registry=https://registry.npmmirror.com
# 检查 Trae 版本
trae version
![Trae 安装验证截图]
二、项目初始化(分步图解)
2.1 创建项目目录
bash
mkdir trae-chatroom && cd trae-chatroom
2.2 使用 Trae 初始化项目
bash
trae init --template websocket-fullstack
选择模板时的交互界面:
scss
? 请选择项目模板 (使用方向键)
❯ WebSocket全栈聊天室
Node.js纯后端服务
React纯前端模板
2.3 项目结构解析
生成的项目目录结构:
csharp
.
├── server/ # 后端服务
│ ├── src/
│ │ ├── config/ # 配置文件
│ │ ├── controllers/ # 控制器
│ │ ├── models/ # 数据模型
│ │ └── services/ # 业务逻辑
│ └── trae.server.json # Trae后端配置
├── client/ # 前端应用
│ ├── public/
│ └── src/
│ ├── assets/ # 静态资源
│ ├── components/ # React组件
│ └── hooks/ # 自定义Hook
└── trae.project.json # 项目级配置
三、后端开发(逐步教学)
3.1 WebSocket 服务器搭建
使用 Trae 生成基础服务:
bash
cd server
trae generate websocket --port 3001 --auth jwt
生成的核心文件 src/services/websocket.service.ts
:
typescript
import { WebSocketServer, WebSocket } from 'ws';
import { JwtService } from './jwt.service';
export class WebSocketService {
private wss: WebSocketServer;
private clients = new Map<WebSocket, string>();
constructor(private port: number = 3001) {
this.wss = new WebSocketServer({ port });
this.setupConnection();
}
private setupConnection() {
this.wss.on('connection', (ws, req) => {
// 身份验证
const token = req.headers['sec-websocket-protocol'];
try {
const payload = JwtService.verify(token);
this.clients.set(ws, payload.userId);
this.sendSystemMessage(`${payload.username} 进入聊天室`);
ws.on('message', (data) => this.handleMessage(ws, data));
ws.on('close', () => this.handleClose(ws));
} catch (error) {
ws.close(1008, '身份验证失败');
}
});
}
private handleMessage(ws: WebSocket, data: Buffer) {
try {
const message = JSON.parse(data.toString());
// 消息验证中间件
if (!this.validateMessage(message)) {
ws.send(JSON.stringify({ type: 'ERROR', code: 4001 }));
return;
}
// 广播消息
this.broadcast(message);
} catch (error) {
console.error('消息处理失败:', error);
}
}
private broadcast(message: any) {
this.wss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(message));
}
});
}
// 其他辅助方法...
}
3.2 添加消息处理逻辑
使用 Trae 生成消息处理器:
bash
trae generate service message --type websocket
生成的消息处理器 src/services/message.service.ts
:
typescript
import { WebSocketService } from './websocket.service';
export class MessageService {
constructor(private wsService: WebSocketService) {}
handleIncomingMessage(ws: WebSocket, rawData: Buffer) {
const message = this.parseMessage(rawData);
switch (message.type) {
case 'TEXT':
this.handleTextMessage(ws, message);
break;
case 'IMAGE':
this.handleImageMessage(ws, message);
break;
case 'COMMAND':
this.handleCommand(ws, message);
break;
default:
this.sendError(ws, '未知消息类型');
}
}
private handleTextMessage(ws: WebSocket, message: any) {
const MAX_LENGTH = 500;
if (message.content.length > MAX_LENGTH) {
this.sendError(ws, '消息过长');
return;
}
const sanitized = this.sanitizeContent(message.content);
this.wsService.broadcast({
type: 'TEXT',
from: this.getClientId(ws),
content: sanitized,
timestamp: Date.now()
});
}
private sanitizeContent(content: string): string {
return content
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/'/g, ''')
.replace(/"/g, '"');
}
// 其他方法...
}
四、前端开发(详细步骤)
4.1 连接 WebSocket
使用 Trae 生成 WebSocket Hook:
bash
cd client
trae generate hook use-chat --type websocket
生成的 src/hooks/useChat.ts
:
typescript
import { useState, useEffect, useCallback } from 'react';
interface Message {
type: string;
content: string;
timestamp: number;
sender?: string;
}
export const useChat = (url: string) => {
const [socket, setSocket] = useState<WebSocket | null>(null);
const [messages, setMessages] = useState<Message[]>([]);
const [error, setError] = useState<string | null>(null);
const connect = useCallback((token: string) => {
const ws = new WebSocket(url, [token]);
ws.onopen = () => {
console.log('WebSocket 连接成功');
setSocket(ws);
};
ws.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
setMessages(prev => [...prev, data]);
} catch (err) {
setError('消息解析失败');
}
};
ws.onerror = (err) => {
setError('连接发生错误');
};
ws.onclose = () => {
setSocket(null);
};
}, [url]);
const sendMessage = useCallback((content: string) => {
if (socket && socket.readyState === WebSocket.OPEN) {
const message = {
type: 'TEXT',
content: content.trim(),
timestamp: Date.now()
};
socket.send(JSON.stringify(message));
}
}, [socket]);
return {
messages,
error,
connect,
sendMessage,
isConnected: socket !== null
};
};
4.2 实现聊天界面
使用 Trae 生成组件:
bash
trae generate component ChatRoom --state=redux --style=scss
生成的 src/components/ChatRoom.tsx
:
tsx
import React, { useState, useEffect } from 'react';
import { useChat } from '../hooks/useChat';
import { useSelector } from 'react-redux';
import { RootState } from '../store';
export const ChatRoom: React.FC = () => {
const [input, setInput] = useState('');
const { user } = useSelector((state: RootState) => state.auth);
const { messages, sendMessage, connect, isConnected } = useChat('ws://localhost:3001');
useEffect(() => {
if (user?.token) {
connect(user.token);
}
}, [user, connect]);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (input.trim() && isConnected) {
sendMessage(input);
setInput('');
}
};
return (
<div className="chat-container">
<div className="message-list">
{messages.map((msg, index) => (
<div key={index} className="message">
{msg.sender && <span className="sender">{msg.sender}:</span>}
<div className="content">{msg.content}</div>
<span className="time">{new Date(msg.timestamp).toLocaleTimeString()}</span>
</div>
))}
</div>
<form onSubmit={handleSubmit} className="message-form">
<input
type="text"
value={input}
onChange={(e) => setInput(e.targetValue)}
placeholder="输入消息..."
disabled={!isConnected}
/>
<button type="submit" disabled={!isConnected}>
{isConnected ? '发送' : '连接中...'}
</button>
</form>
</div>
);
};
五、功能增强(详细配置)
5.1 添加消息持久化
bash
trae add feature message-persistence --database=mongodb --orm=mongoose
生成的数据库配置 server/src/config/mongoose.config.ts
:
typescript
import mongoose from 'mongoose';
const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017/chat';
export const connectDB = async () => {
try {
await mongoose.connect(MONGODB_URI, {
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 45000
});
console.log('MongoDB 连接成功');
} catch (err) {
console.error('数据库连接失败:', err);
process.exit(1);
}
};
// 消息模型
export const MessageSchema = new mongoose.Schema({
content: { type: String, required: true },
sender: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
type: { type: String, enum: ['TEXT', 'IMAGE'], default: 'TEXT' },
timestamp: { type: Date, default: Date.now }
});
export const MessageModel = mongoose.model('Message', MessageSchema);
5.2 实现消息历史查询
bash
trae generate controller MessageController --actions="getHistory,deleteMessage"
生成的控制器 server/src/controllers/message.controller.ts
:
typescript
import { Request, Response } from 'express';
import { MessageModel } from '../config/mongoose.config';
export class MessageController {
static async getHistory(req: Request, res: Response) {
try {
const { page = 1, limit = 50 } = req.query;
const messages = await MessageModel.find()
.sort({ timestamp: -1 })
.skip((Number(page) - 1) * Number(limit))
.limit(Number(limit))
.populate('sender', 'username');
res.json(messages);
} catch (error) {
res.status(500).json({ error: '获取历史消息失败' });
}
}
static async deleteMessage(req: Request, res: Response) {
try {
const { id } = req.params;
const message = await MessageModel.findByIdAndDelete(id);
if (!message) {
return res.status(404).json({ error: '消息不存在' });
}
res.sendStatus(204);
} catch (error) {
res.status(500).json({ error: '删除消息失败' });
}
}
}
六、部署上线(详细流程)
6.1 生产环境构建
bash
# 后端构建
cd server
npm run build
# 前端构建
cd ../client
npm run build
6.2 Docker 部署配置
使用 Trae 生成 Docker 配置:
bash
trae generate docker --compose --nginx
生成的 docker-compose.yml
:
yaml
version: '3.8'
services:
api:
build: ./server
ports:
- "3001:3001"
environment:
- NODE_ENV=production
- MONGODB_URI=mongodb://mongo:27017/chat
depends_on:
- mongo
client:
build: ./client
ports:
- "80:80"
depends_on:
- api
mongo:
image: mongo:6.0
volumes:
- mongo_data:/data/db
ports:
- "27017:27017"
volumes:
mongo_data:
6.3 启动服务
bash
docker-compose up -d --build
七、调试与维护
7.1 实时日志监控
bash
# 查看容器日志
docker-compose logs -f
# Trae 内置监控
trae monitor --service=api --metrics cpu,memory,network
7.2 性能优化示例
bash
trae optimize --service=api --level=high
优化建议输出:
ini
检测到可优化的项目:
1. WebSocket 心跳间隔可调整为 25s(当前 30s)
2. MongoDB 查询建议添加索引:
db.messages.createIndex({ timestamp: -1 })
3. 启用消息压缩:
config.websocket.compression = true
是否应用这些优化?(Y/n)
项目结构总结
通过 Trae 生成的完整项目包含:
- ✅ 用户认证系统
- ✅ WebSocket 实时通信
- ✅ 消息历史记录
- ✅ 管理后台接口
- ✅ 生产环境部署配置
后续学习建议:
- 使用
trae docs generate
生成项目文档 - 通过
trae test --coverage
查看测试覆盖率 - 运行
trae upgrade
保持依赖更新
遇到任何问题可运行 trae doctor
进行环境诊断!