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

Socket.IO与Socket.IO-Client无法连接问题求助(Node.js+React Native)

实时聊天APP Socket.IO连接失败排查方案

问题描述

开发带实时聊天功能的APP,后端采用Node.js+Socket.IO实现,前端React Native使用socket.io-client。当前遇到Socket无法初始化连接的问题:

  • 双方Socket.IO版本均为4.5.1
  • 已尝试降级版本、更换本地端口(3000→4000),问题仍存在
  • 服务器正常运行无报错,但客户端开发控制台显示connected状态为false

服务端代码

const express = require('express');
var bodyParser = require('body-parser');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
const port = process.env.PORT || 3000;

require('./src/config/database')
const user_routes = require('./src/user/users.routes');


app.use(bodyParser.urlencoded({extended: true}))
app.use(express.json())

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

app.use('/User', user_routes)
io.on('connection', (socket) => {
  console.log('a user connected');


  socket.on('send_message',(data)=>{
    console.log("received message in server side",data)
    io.emit('received_message',data)
  })

  socket.on('disconnect', () => {
    console.log('user disconnected');
  });
  
});

server.listen(port, () => {
  console.log( `Server running at http://localhost:${port}/`);
});

客户端Socket服务代码

import io from 'socket.io-client';

const SOCKET_URL = 'http://localhost:3000'

class WSService {

    initializeSocket = async () => {
        try {

            this.socket = io(SOCKET_URL, {
                transports: ['websocket']
            })
            console.log("initializing socket", this.socket)

            this.socket.on('connect', (data) => {
                console.log("=== socket connected ====")
            })

            this.socket.on('disconnect', (data) => {
                console.log("=== socket disconnected ====")
            })

            this.socket.on('error', (data) => {
                console.log("socekt error", data)
            })

        } catch (error) {
            console.log("scoket is not inialized", error)
        }
    }

    emit(event, data = {}) {
        this.socket.emit(event, data)
    }
    
    on(event, cb) {
        this.socket.on(event, cb)
    }

    removeListener(listenerName) {
        this.socket.removeListener(listenerName)
    }

}

const socketServcies = new WSService()

export default socketServcies

排查与解决步骤

1. 修正React Native本地网络访问地址

React Native模拟器/真机访问本地服务器时,localhost无法直接映射:

  • Android模拟器:将SOCKET_URL改为http://10.0.2.2:3000(10.0.2.2是模拟器映射本地电脑的IP)
  • iOS模拟器:可继续用localhost,但真机测试需替换为电脑的局域网IP(如http://192.168.1.105:3000)

2. 配置服务端跨域规则

Socket.IO默认存在跨域限制,需在服务端初始化时添加CORS配置:

const io = new Server(server, {
  cors: {
    origin: "*", // 开发环境允许所有来源,生产环境需指定具体域名
    methods: ["GET", "POST"]
  }
});

3. 调整客户端传输方式

强制指定transports: ['websocket']可能跳过Socket.IO的握手协商阶段,建议去掉该配置,让客户端自动选择合适的传输方式:

this.socket = io(SOCKET_URL); // 移除transports配置

4. 添加详细日志排查错误

  • 服务端添加连接错误日志:
    io.on("connection_error", (err) => {
      console.log("连接错误详情:", err);
    });
    
  • 客户端添加连接状态和错误日志:
    console.log("当前连接状态:", this.socket.connected);
    this.socket.on("connect_error", (err) => {
      console.log("连接失败原因:", err.message);
    });
    

5. 检查端口占用情况

确认服务器端口未被其他程序占用:

  • Windows:netstat -ano | findstr :3000,找到PID后通过任务管理器杀死进程
  • macOS/Linux:lsof -i :3000,执行kill -9 <PID>终止占用进程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:15:46