You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Express+MySQL环境下用户列表的实时同步更新?

解决方案:用WebSocket(Socket.io)实现实时列表更新

轮询确实低效,频繁请求会浪费服务器资源和带宽,推荐用WebSocket实现双向实时通信,其中socket.io是对新手最友好的库——它封装了WebSocket的细节,还能自动适配不支持WebSocket的浏览器。

步骤1:安装必要依赖

在项目里补充安装socket.io(和更易用的mysql2数据库驱动):

npm install express socket.io mysql2

步骤2:改造Express服务器,集成Socket.io

替换原来的Express启动代码,同时支持HTTP和WebSocket通信:

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const mysql = require('mysql2/promise');

const app = express();
const server = http.createServer(app);
// 初始化Socket.io,允许跨域(生产环境要改成具体前端域名)
const io = new Server(server, {
  cors: {
    origin: "*",
    methods: ["GET", "POST"]
  }
});

// 连接MySQL数据库
const db = mysql.createPool({
  host: 'localhost',
  user: '你的数据库用户名',
  password: '你的数据库密码',
  database: '你的数据库名'
});

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

  // 监听用户加入列表的请求
  socket.on('join_list', async (userData) => {
    try {
      // 1. 先把用户数据写入数据库
      await db.execute('INSERT INTO 你的列表表名 (username, ...) VALUES (?, ?)', [userData.username, ...]);
      
      // 2. 广播给所有其他在线用户,通知列表更新
      socket.broadcast.emit('list_updated');
      // 也可以直接查询最新列表再广播,减少前端请求:
      // const [rows] = await db.execute('SELECT * FROM 你的列表表名');
      // socket.broadcast.emit('list_updated', rows);
    } catch (err) {
      console.error('数据库操作失败:', err);
      socket.emit('error', '加入列表失败');
    }
  });

  // 处理用户断开连接
  socket.on('disconnect', () => {
    console.log('用户断开:', socket.id);
  });
});

// 保留原有API,用于加载初始列表
app.get('/api/list', async (req, res) => {
  try {
    const [rows] = await db.execute('SELECT * FROM 你的列表表名');
    res.json(rows);
  } catch (err) {
    res.status(500).json({ error: '获取列表失败' });
  }
});

const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
  console.log(`服务器运行在端口${PORT}`);
});

步骤3:前端代码改造

在页面中引入Socket.io客户端,实现实时监听:

<!-- 引入Socket.io客户端 -->
<script src="/socket.io/socket.io.js"></script>
<script>
  // 连接到后端服务器
  const socket = io('http://localhost:3000');

  // 加载初始列表
  async function loadInitialList() {
    const res = await fetch('/api/list');
    const list = await res.json();
    renderList(list);
  }

  // 渲染列表到页面
  function renderList(list) {
    const listElement = document.getElementById('user-list');
    listElement.innerHTML = list.map(user => `<li>${user.username}</li>`).join('');
  }

  // 监听列表更新事件,自动刷新页面
  socket.on('list_updated', async () => {
    const res = await fetch('/api/list');
    const list = await res.json();
    renderList(list);
    // 如果后端直接发送了列表数据,可直接用:renderList(data);
  });

  // 用户点击加入按钮时触发
  async function joinList() {
    const username = document.getElementById('username').value;
    socket.emit('join_list', { username });
  }

  // 页面加载完成后初始化列表
  window.onload = loadInitialList;
</script>

额外提示

  • 生产环境中,cors配置的origin要改成具体的前端域名,比如"https://your-frontend.com",不要用通配符
  • socket.io会自动处理重连,前端可监听reconnect事件,重新加载列表以保证数据同步
  • 如果后续用户量增大,可引入Redis作为Socket.io的适配器,实现多服务器之间的消息同步,新手先从单服务器版本入手即可

内容的提问来源于stack exchange,提问作者ActiveUseroni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 03:15:48