基于 Trae 的 WebSocket 聊天室保姆级教程(超详细版)

一、环境准备(详细步骤)

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/cli@1.2.5 --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, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/'/g, '&#39;')
      .replace(/"/g, '&quot;');
  }

  // 其他方法...
}

四、前端开发(详细步骤)

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 实时通信
  • ✅ 消息历史记录
  • ✅ 管理后台接口
  • ✅ 生产环境部署配置

后续学习建议

  1. 使用 trae docs generate 生成项目文档
  2. 通过 trae test --coverage 查看测试覆盖率
  3. 运行 trae upgrade 保持依赖更新

遇到任何问题可运行 trae doctor 进行环境诊断!

相关推荐
豆包MarsCode10 小时前
如何用 TRAE Work 做用户增长工具
trae
前端双越老师1 天前
我开发 AI Agent 项目踩过的 5个坑
前端·agent·全栈
飘尘3 天前
前端转型全栈(Java后端)的快速上手指引
前端·后端·全栈
onething3654 天前
Spring Boot + Spring AI 从入门到实战:7天转型计划 Day 5 —— SSE 流式输出 + 打字机效果
人工智能·后端·全栈
onething3654 天前
Spring Boot + Spring AI 从入门到实战:7天转型计划 Day 6 —— 业务完善 + 会话消息预览
人工智能·后端·全栈
东坡白菜5 天前
破局全栈:一个前端开发的Java入门实战记录(1)
java·全栈
七夜zippoe6 天前
DolphinDB WebSocket接入:实时数据流
网络·websocket·网络协议·dolphindb·实时数据流
于先生吖6 天前
从零搭建Java萌宠社交系统:WebSocket实时聊天+动态发布模块实现
java·开发语言·websocket
程序员黑豆7 天前
AI全栈开发系列开篇:从Java全栈到AI应用实战
前端·ai编程·全栈
Captaincc7 天前
TRAE AI创造力大赛,正式启动!
trae·vibecoding