基于Node.js+React的类式Socket.io连接localhost返回404求助
问题分析与修复方案
问题描述
原本常规配置下能建立Socket.io连接,改用类式写法实现后,从localhost访问该连接返回404错误,目标是实现前端与服务端Socket.io成功连接,接收Alchemy SDK Notify Webhook的事件通知。
代码示例
import express, { Application, Request, Response } from 'express'; import * as dotenv from 'dotenv'; import cors from 'cors'; import morgan from 'morgan'; import bodyParser, { json } from 'body-parser'; import homeRouter from './routes/home/homeRouter'; import balanceRouter from './routes/balance/balanceRouter'; import { Server } from 'socket.io'; import http from 'http'; import AlchemyClient from './controller/watcher/watcher.controller'; import mongoose from 'mongoose'; dotenv.config(); const PORT: number = process.env.HTTP_PORT as unknown as number; const DB_URI: string = process.env.DB_URI as string; class MainServer { private app: Application; private server: http.Server; private io: Server; constructor() { this.app = express(); this.server = http.createServer(this.app); this.io = new Server(this.server, { cors: { origin: 'http://localhost:3000', methods: ['GET', 'POST'], }, }); this.connectToDatabase(); this.configApp(); this.configureMiddleware(); this.configureRoutes(); } private configApp(): void { this.app.use(express.json()); this.app.use(cors()); this.app.use(bodyParser.json()); this.app.use(morgan(':method :url :status :response-time ms - :res[content-length]')); } private async connectToDatabase() { try { await mongoose.connect(DB_URI); console.log('Server connected...'); } catch (error) { console.error(error); } } private configureMiddleware() { this.app.use(express.json()); this.app.use(express.urlencoded({ extended: true })); } private configureRoutes(): void { this.app.use('/', homeRouter); this.app.use('/balances', balanceRouter); // this.app.get('/api/start-socket-connection', this.startSocketConnection); this.app.post('/alchemyhook', (req, res) => { // notification received from Alchemy from the webhook. Let the clients know. AlchemyClient.notificationReceived(this.io, req); res.status(200).end(); }); } public start(port: number): void { this.app.listen(port, () => { console.log(`Server started on port ${port}`); }); this.io.on('connection', (socket) => { console.log('Client connected'); socket.on('disconnect', () => console.log('Client disconnected')); socket.on('register address', (msg) => { //send address to Alchemy to add to notification AlchemyClient.registerAddress(msg); }); }); } } const server = new MainServer(); server.start(PORT);
核心问题
你在start方法中启动的是Express的app实例,但Socket.io是绑定在this.server(由http.createServer(this.app)创建的HTTP服务器实例)上的。直接启动app实例会导致Socket.io无法监听WebSocket连接请求,前端访问时自然返回404。
修复方案
修改start方法,启动绑定了Socket.io的HTTP服务器实例,而非Express的app:
public start(port: number): void { // 替换this.app.listen为this.server.listen this.server.listen(port, () => { console.log(`Server started on port ${port}`); }); this.io.on('connection', (socket) => { console.log('Client connected'); socket.on('disconnect', () => console.log('Client disconnected')); socket.on('register address', (msg) => { AlchemyClient.registerAddress(msg); }); }); }
额外优化建议
- 移除冗余的中间件:
configApp和configureMiddleware中重复添加了express.json(),保留一处即可,避免不必要的重复处理。 - 前端连接验证:确保前端代码使用正确的连接方式,例如:
Socket.io会自动处理默认的import { io } from 'socket.io-client'; const socket = io('http://localhost:你的端口号');/socket.io路径请求,无需手动添加。
内容的提问来源于stack exchange,提问作者MDIPANJAN
相关产品推荐
相关产品推荐

