React Native无法连接Socket IO的问题排查求助
React Native Socket.IO 连接问题排查与解决
问题现象
在React Native中尝试连接Socket.IO服务时,遇到三类错误:
- 直接使用
https://socket-dev.com时,报错:Unable to resolve host "socket-dev.com": No address associated with hostname - 改用环境变量
env.SOCKET_URL时,报错:Unable to resolve host "undefined": No address associated with hostname - 直接填写带5000端口的URL时,应用崩溃并提示:
Invalid URL PORT: 5000
已知背景:
- Electron和Web应用可正常连接本地Socket服务
- AndroidManifest.xml已配置
<uses-permission android:name="android.permission.INTERNET"/>权限 - 使用的
socket.io-client版本为^4.7.5
原代码示例
import { createContext, useContext, useEffect, useRef, useState } from "react"; import client, { Socket } from "socket.io-client"; import { env } from "../constants/env"; import { useAuth } from "./AuthContext"; interface SocketContextType { socket: Socket | null; } const SocketContext = createContext({ socket: null } as SocketContextType); const socketConfig = { jsonp: false, autoConnect: false, secure:true, // path: env.SOCKET_PATH, transports: ["websocket"], }; type Props = { children: React.ReactNode; }; export default function SocketProvider({ children }: Props) { const { user } = useAuth(); const socket = useRef(client('https://socket-dev.com', socketConfig)); useEffect(() => { if (!user) return; socket.current.auth = { id_instituicao: user?.id_instituicao, usuario: user?.user, ambiente: "app", }; console.log(socket.current) socket.current.connect(); socket.current.on("connect", () => { console.log("Conectado"); }); socket.current.on("connect_error", (error) => { console.log("Erro de conexão:", error); }); socket.current.on("disconnect", (msg) => { console.log("SocketIO: Disconnect", msg); socket.current = client('https://socket-dev.com', socketConfig); }); return () => { if (socket && socket.current) { socket?.current?.removeAllListeners(); socket?.current?.close(); } }; }, []); return ( <SocketContext.Provider value={{ socket: socket.current }}> {children} </SocketContext.Provider> ); } const useSocket = () => useContext(SocketContext); export { useSocket };
排查与解决步骤
1. 修复环境变量undefined问题
出现Unable to resolve host "undefined",说明env.SOCKET_URL未正确加载:
- 检查
.env配置文件是否存在,SOCKET_URL是否正确定义,格式示例:SOCKET_URL=http://192.168.x.x:5000(本地服务用局域网IP,不能用localhost) - 若使用
react-native-dotenv,确认babel.config.js已配置插件:
module.exports = { plugins: [ ["module:react-native-dotenv", { moduleName: "@env", path: ".env", safe: false, allowUndefined: true, }] ] };
- 重启Metro服务,确保环境变量生效。
2. 解决主机解析失败问题
Unable to resolve host "socket-dev.com"属于网络连通性问题:
- 在测试设备(模拟器/真机)的浏览器中打开
https://socket-dev.com,验证是否能正常访问 - 若连接本地服务:Android模拟器用
10.0.2.2映射电脑localhost,真机直接用电脑的局域网IP(如192.168.1.100)
3. 修复端口无效问题
Invalid URL PORT: 5000多因URL格式或协议不匹配:
- 确认URL格式正确:本地HTTP服务用
http://192.168.x.x:5000,HTTPS服务用https://socket-dev.com:5000 - 匹配
secure参数:HTTP服务设secure: false,HTTPS服务设secure: true - 检查服务端是否允许该端口的跨域连接
4. 优化Socket连接逻辑
原代码存在初始化时机和重连逻辑问题,建议调整:
const socket = useRef<Socket | null>(null); useEffect(() => { if (!user) return; // 延迟初始化socket,绑定auth参数 socket.current = client(env.SOCKET_URL, { jsonp: false, autoConnect: false, secure: env.SOCKET_URL.startsWith("https"), transports: ["websocket"], auth: { id_instituicao: user.id_instituicao, usuario: user.user, ambiente: "app", } }); socket.current.on("connect", () => console.log("Conectado")); socket.current.on("connect_error", (err) => console.log("Erro de conexão:", err)); socket.current.on("disconnect", (msg) => console.log("SocketIO: Disconnect", msg)); socket.current.connect(); return () => { socket.current?.removeAllListeners(); socket.current?.close(); socket.current = null; }; }, [user]); // 依赖user状态,用户信息变化时重建连接
- 利用Socket.IO默认的自动重连机制(无需手动重新创建实例),可通过
reconnection: true显式开启
5. 额外适配检查
- Android 9及以上设备连接HTTP服务时,需在
AndroidManifest.xml中添加:
<application ... android:usesCleartextTraffic="true">
- 确认React Native版本与
socket.io-client@4.7.5兼容,无版本冲突
内容的提问来源于stack exchange,提问作者Willian Louza
相关产品推荐
相关产品推荐

