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
相关产品推荐
相关产品推荐

