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

NestJS与React Native(Expo)中Socket.IO无法正常通信问题求助

问题分析与解决方案

核心问题在于版本兼容配置缺失、客户端连接实例管理不当以及跨域/网络权限配置遗漏,以下是针对性修复步骤:


1. 修复NestJS网关的CORS配置

React Native属于跨域环境,即使是本地IP连接,也需要显式配置WebSocket网关允许跨域:

import { MessageBody, SubscribeMessage, WebSocketGateway, WebSocketServer } from "@nestjs/websockets";
import { Logger } from "@nestjs/common";

@WebSocketGateway({
  cors: {
    origin: "*", // 开发环境临时用*,生产环境替换为你的移动端域名/IP
    credentials: true,
  },
})
export class ChatGateway {
  private logger = new Logger('ChatGateway');
  
  @WebSocketServer()
  server;

  // 添加连接日志,便于排查
  handleConnection(client: any) {
    this.logger.log(`客户端已连接:${client.id}`);
  }

  @SubscribeMessage('message')
  handleMessage(@MessageBody() message: string): void {
    this.logger.log(`收到消息:${message}`);
    this.server.emit('message', message);
  }
}

2. 修复React Native客户端的Socket实例管理

原代码在组件顶层创建Socket实例,会导致组件每次渲染都新建连接,引发状态混乱。改用useRef保存实例,并确保仅初始化一次:

import { useState, useEffect, useRef } from 'react';
import { View, Text, TextInput, Button } from 'react-native';
import io from 'socket.io-client';

const ChatScreen = () => {
  const [message, setMessage] = useState("");
  const [receivedMessage, setReceivedMessage] = useState("");
  const socketRef = useRef(null);

  useEffect(() => {
    // 仅初始化一次Socket连接
    socketRef.current = io("http://192.168.1.22:3000", {
      transports: ["websocket"],
      forceNew: true,
    });

    const socket = socketRef.current;

    // 添加错误监听,排查连接异常
    socket.on("connect_error", (err) => {
      console.error("连接错误:", err);
    });
    socket.on("connect", () => {
      console.log("WebSocket已连接");
    });
    socket.on("message", (msg) => {
      setReceivedMessage(msg);
    });

    return () => {
      socket.disconnect();
    };
  }, []); // 空依赖,确保仅执行一次

  const sendMessage = () => {
    try {
      socketRef.current?.emit("message", message);
      setMessage("");
    } catch (error) {
      console.error("发送消息失败:", error);
    }
  };

  return (
    <View style={{ padding: 20 }}>
      <Text style={{ marginBottom: 10 }}>收到的消息:{receivedMessage}</Text>
      <TextInput
        placeholder="输入消息"
        value={message}
        onChangeText={setMessage}
        style={{ borderWidth: 1, padding: 10, marginBottom: 10 }}
      />
      <Button title="发送" onPress={sendMessage} />
    </View>
  );
};

export default ChatScreen;

3. 配置React Native网络权限

iOS默认禁止明文HTTP连接,Android需要显式开启明文流量,在app.json中添加:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSAppTransportSecurity": {
          "NSAllowsArbitraryLoads": true
        }
      }
    },
    "android": {
      "usesCleartextTraffic": true
    }
  }
}

4. 版本兼容调整(可选)

@nestjs/platform-socket.io@8.4.5依赖的socket.io版本为4.5.x,若上述修复仍无效,可将客户端版本降级到匹配的4.5.4:

npm install socket.io-client@4.5.4

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 19:12:22