在cPanel部署Socket.IO Node.js应用时出现GET 404错误求助
cPanel部署Node.js应用遇Socket.IO 404错误问题排查与解决
问题现象
在cPanel主机部署Node.js应用后,页面可正常打开,但Node.js无法向客户端发送数据,浏览器控制台出现如下错误:
GET http://streamedbot.xyz/socket.io/?EIO=3&transport=polling&t=OFQdTfs 404 (Not Found)
应用代码(app.js)
const fetchP2PData = require("./fetchP2PData.js"); const app = require("express")(); const path = require("path"); const Datastore = require("nedb"); const { createServer } = require('http') const { Server } = require('socket.io') const server = createServer(app) const io = new Server(server, { cors: { origin: "*", methods: ["GET", "POST"], credentials: false, transports: ['websocket', 'polling'], }, allowEIO3: true }) app.get('/bkpapp/', function(req,res){ res.sendFile(__dirname + '/index.html'); }); let prices = []; let openingPrice = 0 ; const priceDb = new Datastore("./price.db"); priceDb.loadDatabase(); priceDb.find({}, { time: 1, value: 1, _id: 0 }, function (err, docs) { docs.reverse(); prices = docs; console.log(prices); }); setInterval(function () { (async function () { let totalPrices = []; const firstPage = await fetchP2PData(1, "ETB", "BUY", "USDT", null); if (firstPage && firstPage.success) { const totalPages = Math.ceil(firstPage.total / 20); const pagesToRun = new Array(totalPages - 1).fill(null); const totalElements = await pagesToRun.reduce(async (prev, _, idx) => { const accData = await prev; const page = idx + 2; const pageResult = await fetchP2PData(page, "ETB", "BUY", "USDT", null); if (pageResult && pageResult.success) { return [...accData, ...pageResult.data]; } return accData; }, Promise.resolve(firstPage.data)); totalElements.map((obj) => { totalPrices.push(parseFloat(obj.adv.price)); }); } let currentPrice = ((totalPrices[0]+totalPrices[1]+totalPrices[2]+totalPrices[3]+totalPrices[4]+totalPrices[5]+totalPrices[6]+totalPrices[7]+totalPrices[8]+totalPrices[9]+totalPrices[10])/11)-3.95; const d = new Date(); if(d.getHours() == 00 && d.getMinutes() == 00){ openingPrice = currentPrice; } let dailyPercentage = ((currentPrice - openingPrice)/openingPrice)*(100) prices.push({ time: d.getTime()/1000, value: (((totalPrices[0]+totalPrices[1]+totalPrices[2]+totalPrices[3]+totalPrices[4]+totalPrices[5]+totalPrices[6]+totalPrices[7]+totalPrices[8]+totalPrices[9]+totalPrices[10])/11)-3.95)}) io.on('connection', sock => { }) if(totalPrices != null){ io.sockets.emit('price', prices) priceDb.insert({ time: d.getTime()/1000, value: (((totalPrices[0]+totalPrices[1]+totalPrices[2]+totalPrices[3]+totalPrices[4]+totalPrices[5]+totalPrices[6]+totalPrices[7]+totalPrices[8]+totalPrices[9]+totalPrices[10])/11)-3.95)}); io.sockets.emit('dailyPercentage', dailyPercentage) } console.log(prices); })(); }, 10000); server.listen(3000, function(){ console.log('listening to 80') })
解决步骤
1. 修正Socket.IO路径匹配cPanel应用路由
cPanel部署Node.js应用时,会通过反向代理将/bkpapp/路径映射到本地3000端口。Socket.IO默认使用根路径/socket.io/,导致和cPanel的代理路径不匹配,触发404错误。
- 服务端修改:给Socket.IO添加
path配置,匹配应用路径:const io = new Server(server, { cors: { origin: "*", methods: ["GET", "POST"], credentials: false, transports: ['websocket', 'polling'], }, allowEIO3: true, path: '/bkpapp/socket.io/' // 新增该行,与应用路由对齐 }) - 客户端修改(index.html中的Socket.IO连接代码):指定连接路径为
/bkpapp/:const socket = io('/bkpapp/', { transports: ['websocket', 'polling'], allowEIO3: true });
2. 移除重复绑定的connection事件
代码在setInterval定时器内重复执行io.on('connection', ...),每次定时器触发都会新增一个连接监听,会造成资源泄漏且影响连接逻辑。将这段代码移到定时器外部,只绑定一次:
// 移到setInterval外面,仅初始化时绑定一次 io.on('connection', sock => { console.log('客户端已连接'); // 可选:给新连接发送初始数据 sock.emit('price', prices); sock.emit('dailyPercentage', openingPrice ? ((prices[prices.length-1].value - openingPrice)/openingPrice)*100 : 0); }) setInterval(function () { // ... 原有定时器代码,删除里面的io.on('connection')块 }, 10000);
3. 修正服务器监听日志
代码中监听3000端口,但日志输出listening to 80,容易造成混淆,修正为实际监听端口:
server.listen(3000, function(){ console.log('listening on port 3000') })
4. 检查cPanel应用配置
- 确认cPanel中Node.js应用的根目录指向包含
app.js的文件夹 - 验证启动命令为
node app.js - 确认应用的挂载路径设置为
/bkpapp/,反向代理正确映射到3000端口
内容的提问来源于stack exchange,提问作者zemen aferash
相关产品推荐
相关产品推荐

