boxmoe_header_banner_img

她是我的浮木,也是我最后的故乡!

加载中

文章导读

express + socket.io 实现聊天服务端


avatar
浮木 2025年3月4日 109
  1. 数据库(必选)

    • MongoDB(推荐): 文档型数据库适合聊天消息的灵活存储

    • 或 MySQL/PostgreSQL: 需要设计 messages 表结构

    • 使用 Mongoose(MongoDB)或 Sequelize(SQL)作为 ORM

  2. 消息模型(必选)

    // MongoDB Schema 示例
    const messageSchema = new mongoose.Schema({
      content: String,
      sender: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, // 或直接存用户名
      timestamp: { type: Date, default: Date.now },
      room: String  // 支持群聊时需要
    });

3.身份认证

(推荐)

JWT + Express-middleware 实现 Token 验证

或 Passport.js 实现 OAuth/本地认证


进阶方案(生产级)

4. **消息分页**(必选)
   - 实现按时间倒序的分页查询
   ```javascript
   // MongoDB 分页示例
   async function getHistory(room, page = 1, limit = 50) {
     return await Message.find({ room })
       .sort({ timestamp: -1 })
       .skip((page - 1) * limit)
       .limit(limit)
       .exec();
   }
   
  1. 文件存储(可选)

    • 使用 AWS S3/MinIO 存储图片/文件

    • 消息中保存文件 URL

  2. 消息同步(高级)

    • Redis 缓存最新消息

    • 使用 RabbitMQ/Kafka 实现跨服务器消息同步(分布式部署时)


最小完整示例(Express + Socket.io + MongoDB)

import express from 'express';
import { createServer } from 'http';
import { Server } from 'socket.io';
import mongoose from 'mongoose';

// MongoDB 连接
mongoose.connect('mongodb://localhost/chat');

// 消息模型
const Message = mongoose.model('Message', new mongoose.Schema({
  content: String,
  sender: String,
  timestamp: Date
}));

const app = express();
const httpServer = createServer(app);
const io = new Server(httpServer);

// Socket.io 处理
io.on('connection', (socket) => {
  console.log('用户连接');

  // 历史消息请求
  socket.on('requestHistory', async () => {
    const messages = await Message.find().sort({ timestamp: -1 }).limit(50);
    socket.emit('messageHistory', messages.reverse());
  });

  // 消息处理
  socket.on('sendMessage', async (msg) => {
    // 存储到数据库
    const newMsg = new Message({
      content: msg.content,
      sender: msg.sender,
      timestamp: new Date()
    });
    await newMsg.save();

    // 广播消息
    io.emit('newMessage', newMsg);
  });

  socket.on('disconnect', () => {
    console.log('用户断开');
  });
});

httpServer.listen(3000, () => {
  console.log('服务运行在 3000 端口');
});

后续扩展建议

1. 消息状态管理:已读/未读状态
2. 敏感词过滤:使用正则表达式或第三方过滤服务
3. 消息搜索:Elasticsearch 实现全文搜索
4. 性能优化:Redis 缓存高频访问的历史消息
5. 负载均衡:使用 Nginx + 多 Node 实例


评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字
插入代码