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

React Native不使用Hooks时如何异步初始化Socket.io单例连接

React Native Socket.io 单例异步初始化解决方案

问题根源

  1. 直接在io()配置中使用await get_token():io是同步执行函数,await会返回Promise对象,导致服务端收到的Authorization头为Bearer [object Object]。
  2. 将Socket改为异步函数导出:组件调用时直接拿到的是Promise而非Socket实例,且未做单例缓存,可能重复创建连接。
  3. 先初始化Socket再修改extraHeaders:Socket初始化时已发送连接请求,后续修改头信息不会同步到已发出的请求,服务端无法获取正确token。

可行方案:Promise缓存的单例模式

通过缓存Socket实例和初始化Promise,确保io()仅执行一次,且在异步获取token后完成Socket初始化。

实现代码(socket.js)

import io from 'socket.io-client';
import EncryptedStorage from 'react-native-encrypted-storage';

let socketInstance = null;
let initPromise = null;

// 异步获取token
const getToken = async () => {
  try {
    return await EncryptedStorage.getItem('userToken');
  } catch (err) {
    console.error('获取用户token失败:', err);
    return null;
  }
};

// 获取Socket单例的方法
export const getSocket = async () => {
  // 已有实例直接返回
  if (socketInstance) return socketInstance;
  // 正在初始化则返回同一个Promise,避免重复请求token
  if (initPromise) return initPromise;

  // 执行初始化流程
  initPromise = (async () => {
    const token = await getToken();
    socketInstance = io('你的Socket服务端地址', {
      extraHeaders: {
        Authorization: token ? `Bearer ${token}` : ''
      },
      // 可添加其他Socket配置(如超时、重连策略等)
    });

    // 监听连接状态,可选:断开连接时重置实例,方便后续重连
    socketInstance.on('disconnect', () => {
      socketInstance = null;
      initPromise = null;
      console.log('Socket连接已断开');
    });

    return socketInstance;
  })();

  return initPromise;
};

组件中使用方式

在需要使用Socket的组件中,通过异步方式获取实例:

import { useEffect } from 'react';
import { getSocket } from './socket';

const ChatComponent = () => {
  useEffect(() => {
    const setupSocket = async () => {
      const socket = await getSocket();
      // 监听聊天消息等事件
      socket.on('chat_message', (message) => {
        console.log('收到消息:', message);
        // 处理消息逻辑
      });
    };

    setupSocket();

    // 组件卸载时断开连接(可选)
    return async () => {
      const socket = await getSocket();
      socket.disconnect();
    };
  }, []);

  // 组件其他逻辑
  return <></>;
};

方案优势

  • 保证io()仅执行一次,完全符合单例需求。
  • 异步获取token后再初始化Socket,确保服务端能拿到正确的Authorization头,关联用户与socket.id。
  • 通过initPromise缓存初始化流程,避免多个组件同时调用时重复请求token和创建Socket实例。
  • 可选处理断开连接的场景,重置实例后下次获取会重新初始化,适配token过期后重连的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:50:24