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

socket.io v4如何防范恶意滥发连接导致多人游戏服务器崩溃

解决方案

1. Socket.IO v4 获取客户端IP的方法

Socket.IO v4 中客户端IP可以直接从 socket.handshake.address 属性获取,如果你将服务端部署在Nginx等反向代理后,需要先配置代理传递真实IP,此时可以从 socket.handshake.headers['x-forwarded-for'] 中获取真实客户端IP。
示例代码:

io.on('connection', (socket) => {
  // 直接获取IP(无反向代理场景)
  const clientIP = socket.handshake.address;
  // 反向代理场景下获取真实IP
  // const clientIP = socket.handshake.headers['x-forwarded-for']?.split(',')[0] || socket.handshake.address;
  console.log(`客户端 ${clientIP} 已连接`);

  // 其余原有逻辑
})

2. 基于IP的速率限制实现

你可以通过内存对象/Map来统计每个IP的连接次数、事件触发频率,超出阈值直接拒绝连接或者忽略请求即可,示例实现如下:

// 存储IP速率限制统计,key为IP,value为统计对象
const ipRateLimit = new Map();
// 速率限制配置
const RATE_CONFIG = {
  // 统计窗口时间,单位毫秒,这里设为10秒
  WINDOW_MS: 10 * 1000,
  // 单IP最大连接数 per 窗口
  MAX_CONNECTIONS: 5,
  // 单IP最大go事件触发次数 per 窗口
  MAX_GO_REQUESTS: 2
};

// 定时清理过期的统计数据,避免内存泄漏
setInterval(() => {
  const now = Date.now();
  for (const [ip, stats] of ipRateLimit.entries()) {
    if (now > stats.resetTime) {
      ipRateLimit.delete(ip);
    }
  }
}, RATE_CONFIG.WINDOW_MS);

io.on('connection', (socket) => {
  const clientIP = socket.handshake.address;
  const now = Date.now();

  // 初始化该IP的统计数据
  if (!ipRateLimit.has(clientIP)) {
    ipRateLimit.set(clientIP, {
      connections: 0,
      goRequests: 0,
      resetTime: now + RATE_CONFIG.WINDOW_MS
    });
  }
  const ipStats = ipRateLimit.get(clientIP);

  // 连接数超出阈值,直接断开连接
  if (ipStats.connections >= RATE_CONFIG.MAX_CONNECTIONS) {
    socket.disconnect();
    return;
  }
  ipStats.connections += 1;

  socket.on("go", (name) => {
    // go事件触发超出阈值,忽略请求,也可以选择直接断开连接
    if (ipStats.goRequests >= RATE_CONFIG.MAX_GO_REQUESTS) {
      return;
    }
    ipStats.goRequests += 1;
    addPlayer(name);
  })
  
  socket.on("move", (angle) => {
    // 原有移动逻辑,也可以按需增加速率限制
  })

  // 连接断开时减少连接计数
  socket.on('disconnect', () => {
    if (ipStats.connections > 0) {
      ipStats.connections -= 1;
    }
  })
})

3. 生产环境优化建议

  • 如果是多实例部署的Socket.IO服务,将速率限制统计数据存在Redis中即可实现跨实例的速率限制
  • 可以根据业务需求调整阈值,正常用户不会在短时间内多次创建连接、多次触发新建玩家的go事件,阈值设置为远高于正常用户操作频率即可
  • 对于确认是恶意攻击的IP,可以直接加入黑名单长期拒绝连接

内容的提问来源于stack exchange,提问作者Coder Gautam YT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 02:24:03