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

React客户端与Socket.io服务端连接报错求助

Socket.io连接报错排查(React国际象棋PVP游戏开发)

我正在跟着教程开发React版PVP国际象棋游戏,游戏逻辑已完成,目前用websockets(socket.io)实现玩家加入和走棋同步功能。浏览器控制台捕获到Websocket连接报错:

Websocket connection error:  Error: server error
    onPacket socket.js:335
    node_modules bundle.js:46361
    onPacket transport.js:98
    callback polling.js:116
    onData polling.js:119
    node_modules bundle.js:46361
    onLoad polling.js:352
    onreadystatechange polling.js:288

该错误通过以下代码捕获:

socket.on('connect_error', (error) => {
        console.log('Websocket connection error: ', error)
    })

已排除CORS问题(socket.active返回true且无CORS报错),但问题仍未解决。

服务端代码(index.js)

const http = require('http');
const socketio = require('socket.io');
const express = require('express');
const { addPlayer, game, removePlayer } = require('./game');
const cors = require('cors');

const app = express();

app.use(cors());
app.use(express.json());
app.get('/', (req, res) => res.send({ status: 'healthy' }));
const server = http.createServer(app);
const PORT = process.env.PORT || 5000;

const io = socketio(server);


server.listen(PORT, () => console.log('Server running on port ' + PORT));
io.on('connection', (socket) => {
    console.log("connections")
    socket.on('connect_error', (error) => {
        console.log(error)
     });
    socket.on('join', ({ name, gameID }, callback) => {
        const { error, player, opponent } = addPlayer({
            gameID,
            name,
            playerID: socket.id,
        });
        console.log(player)
        if (error) {
            return callback({ error })
        }

        socket.join(gameID);
        callback({ colour: player.colour });

        socket.emit('welcome', {
            message: `Hello ${player.name},  Welcome to the game`,
            opponent,
        });

        socket.broadcast.to(player.gameID).emit('opponentJoin', {
            message: `${player.name} has joined the game. `,
            opponent: player
        });
    
        if (game(gameID).length >= 2){
            const white = game(gameID).find((player) => player.colour === 'w');
            io.to(gameID).emit('message', {
                message: `Let's start the game. White (${white.name}) goes first`,
            });
        }
    });

    socket.on('move', ({ from, to, gameID }) => {
        socket.broadcast.to(gameID).emit('opponentMove', { from, to });
    });

    socket.on('disconnect', () => {
        const player = removePlayer(socket.id);

        if (player) {
            io.to(player.game).emit('message', {
                message: `${player.name} has left the game.`,
            });
            socket.broadcast.to(player.game).emit('opponentLeft');
        }
    });

});

客户端相关Socket代码

import io from 'socket.io-client';

useEffect(() => {
    console.log(socket.active)
    socket.on('connect_error', (error) => {
        console.log('Websocket connection error: ', error)
    })
    socket.on('connect', () => {
        console.log(socket)
        console.log('Socket connected');
        socket.emessageit('join', { name: 'Frank', gameID: '20' }, ({ error, color }) => {
            console.log({ color });
        });
        socket.on('Welcome', ({ message, opponent }) => {
            console.log({ message, opponent });
        });
        socket.on('opponentJoin', ({ message, opponent }) => {
            console.log({ message, opponent });
        });

        socket.on('opponentMove', ({ from, to }) => {
            chess.move({ from, to });
            setFen(chess.fen());
        });
    })
}, [chess]);

排查修复点

  1. 修正客户端拼写错误

    • 把socket.emessageit('join', ...)改为socket.emit('join', ...),这是明显的笔误
    • 客户端监听的'Welcome'事件名要改成小写的'welcome',服务端发送的事件名是小写,大小写不匹配会导致无法接收消息,进而触发连接错误
  2. 确认Socket实例初始化正确性
    确保客户端正确初始化socket,指定服务端的正确地址,比如:

    const socket = io('http://localhost:5000'); // 按服务端实际运行地址调整
    
  3. 排查服务端游戏逻辑错误
    "server error"通常是服务端代码抛出未捕获异常导致的,建议在join事件处理中添加try-catch捕获错误:

    socket.on('join', ({ name, gameID }, callback) => {
        try {
            const { error, player, opponent } = addPlayer({
                gameID,
                name,
                playerID: socket.id,
            });
            console.log(player)
            if (error) {
                return callback({ error })
            }
    
            // 原有逻辑保持不变
        } catch (err) {
            console.error('加入游戏时出错:', err);
            callback({ error: err.message });
        }
    });
    

    同时检查./game模块里的addPlayer和game函数,确认没有数组越界、未定义变量等逻辑错误。

  4. 添加全局错误监听
    在服务端添加全局的Socket错误监听,方便捕获更多层面的错误:

    io.on('connect_error', (error) => {
        console.log('全局连接错误:', error);
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:05:19