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

Node.js遇Error: listen EADDRINUSE报错,常规方案无效求排查

问题分析与解决办法

我仔细梳理了你的代码,导致Error: listen EADDRINUSE的核心原因是WebSocket服务器的关闭操作是异步的,但你没有等待它完全释放端口就再次启动监听,另外代码里还有几处逻辑错误会加重这个问题,下面一步步拆解解决:

1. 核心问题:异步关闭未等待,重复抢占端口

你的启动器代码中,在exec的回调里直接调用wss.close()后立刻执行fun(),但wss.close()是异步操作——它需要等待所有连接断开、服务器彻底停止后才会释放端口。此时新的wss.listen()尝试使用还被旧服务器占用的端口,自然会抛出端口被占用的错误。

修改启动器代码,等待服务器完全关闭再重启:

var exec = require('child_process').execFile;
const wss = require('./ws_server/wss');
const config = require('./config');

async function fun() {
  const process = exec(`${config.EXE.PATH}/${config.EXE.NAME}`, async () => {
    // 用Promise包裹close操作,确保端口完全释放后再重启
    await new Promise(resolve => wss.close(resolve));
    fun();
  });

  if (process.pid != null && process.pid !== undefined) {
    try {
      // 移除重复的error事件绑定(服务器端已处理)
      wss.listen({port: config.PORT, host: config.HOST}, () => {
        console.log((new Date()) + ` Server is listening on port ${config.PORT}`);
      });
    } catch(err) {
      console.error('启动服务器失败:', err);
    }
  }
}

fun();

2. 连接清理逻辑的两处错误

你的WebSocket服务器代码中,维护连接列表的逻辑有问题,会导致无效连接无法被正确清理,甚至可能影响服务器关闭效率:

  • 变量名拼写错误:ConnectionsList.splice(index); 应该是小写的connectionsList
  • forEach中使用splice会导致索引错乱:删除某个元素后,后续元素会前移,但forEach的索引会继续递增,导致跳过部分连接

修改WebSocket服务器的连接清理逻辑:

wsServer.on('connection', function (connection) {
  connectionsList.push(connection);
  connection.on('message', function (message) {
    const data = JSON.parse(message) || null;
    if (data !== null && data.type === 'push') {
      // 先过滤掉已关闭的连接,更新列表
      connectionsList = connectionsList.filter(conn => conn.state !== 'closed');
      // 用对象对比跳过消息发送者,比index判断更准确
      connectionsList.forEach(conn => {
        if (conn !== connection) {
          conn.send(JSON.stringify(data.message));
        }
      });
    }
  });

  // 监听连接关闭事件,实时清理无效连接
  connection.on('close', () => {
    connectionsList = connectionsList.filter(conn => conn !== connection);
  });
});

3. 其他优化细节

  • 移除启动器中重复的wss.on('error')绑定:你的WebSocket服务器代码里已经绑定了错误监听,重复绑定会导致多个监听器触发,增加调试复杂度
  • 验证config.EXE.PATH和config.EXE.NAME的路径正确性:避免因exe进程启动失败导致服务器无限重启,加重端口占用问题
  • Windows Server上可通过netstat -ano | findstr :<你的端口>命令,确认端口占用情况,验证修复效果

按以上步骤修改后,应该就能彻底解决EADDRINUSE的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:37:54