Node.js环境Socket.IO请求6次后无法获取ID问题求助
问题根因
- 最核心的问题是你的POST路由没有给客户端返回任何响应,也没有主动结束请求。主流浏览器对同一个域名的并发请求上限默认是6个,前6次请求发出后一直处于等待响应的挂起状态,后续的请求会被浏览器暂存在本地队列中,不会实际发送到服务端,所以你看不到后续的id打印。服务端重启后,之前挂起的请求会重新发起,所以会一次性收到之前所有的id。
- 你创建的
clientUDP套接字没有用let/const声明,属于全局变量,每次请求都会覆盖上一次的实例,还会造成内存和文件描述符泄漏,请求次数多了会触发资源上限。 - UDP套接字使用完成后没有主动关闭,一直占用系统资源。
- 若你没有在其他地方配置express的body解析中间件,
req.body会是undefined,也会导致拿不到id。
修复方案
修改后的代码如下:
const express = require("express"); const dgram = require('dgram'); // 替换为实际的UDP服务配置 const UDP_PORT = 1234; const UDP_HOST = '127.0.0.1'; var closeFlag = false; const PORT = process.env.SERVER_PORT || 3000; const app = express(); // 新增body解析中间件,用于解析POST请求体 app.use(express.json()); app.use(express.urlencoded({ extended: true })); var count = 1; const http = require('http'); http.globalAgent.maxSockets = 100; http.Agent.maxSockets = 100; const serverTCP = http.createServer(app) const tcpsock = require('socket.io')(serverTCP, { cors: { origin: '*', }, perMessageDeflate: false }); app.post("/getchanneldata", (req, res) => { console.log("count : "+count) count++; closeFlag = false; const message = (req.body.val).toString() console.log("message : "+message); // 改为局部变量,避免全局污染 const chanId = message; // 用const声明局部UDP实例,避免覆盖全局变量 const client = dgram.createSocket({ type: 'udp4', reuseAddr: true }); client.on('listening', () => { const address = client.address(); }); client.on('message', function (message1, remote) { const arr = message1.toString().split(','); // 此处可添加Socket.IO推送逻辑,把数据推送给前端 tcpsock.emit('channelData', { id: chanId, data: arr }); // 处理完成后关闭UDP套接字释放资源 client.close(); // 主动返回HTTP响应,结束当前请求 res.send({ code: 200, data: arr }); }); client.send(message, 0, message.length, UDP_PORT, UDP_HOST, function (err, bytes) { if (err) { console.error('UDP消息发送失败:', err); client.close(); // 出错也要返回响应,避免请求一直挂起 res.status(500).send({ code: 500, msg: '请求失败' }); return; } console.log(message); console.log('UDP client message sent to ' + UDP_HOST + ':' + UDP_PORT); }); client.on('close', () => { console.log('UDP套接字已释放'); }); // 新增错误捕获,避免单个请求异常导致服务崩溃 client.on('error', (err) => { console.error('UDP套接字异常:', err); client.close(); res.status(500).send({ code: 500, msg: err.message }); }); }); serverTCP.listen(PORT, () => { console.log('服务已启动,端口:', PORT); });
- 每一次请求处理完成或出错时都主动返回HTTP响应,结束请求,避免占用并发连接配额。
- 所有变量使用
const/let声明,避免全局变量污染。 - UDP套接字使用完成后主动关闭,避免资源泄漏。
- 补充错误处理逻辑,提升服务稳定性。
内容的提问来源于stack exchange,提问作者salik saleem
相关产品推荐
相关产品推荐

