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

React Native应用Android唤醒后实时监听失效问题求助

问题原因分析
  • Android设备休眠时,系统会优先限制后台网络连接以节省电量,主动切断WebSocket长连接,导致Pusher频道监听失效。
  • 当前代码未实现自动重连机制,连接断开后无法主动恢复与服务器的通信。
  • 未监听应用状态变化(如休眠唤醒后应用回到前台),无法触发连接恢复逻辑。
解决方案建议

1. 配置Echo自动重连

Laravel Echo内置重连相关配置,初始化时添加参数让客户端在连接断开后自动尝试重连:

const connectToWebSocket = async () => {
  try {
    const ws = new Echo({
      broadcaster: 'pusher',
      Pusher,
      key: appConfig.apiKay,
      wsHost: appConfig.backendUrl,
      wssHost: appConfig.backendUrl,
      wsPort: 6001,
      wssPort: 6001,
      forceTLS: true,
      encrypted: true,
      cluster: 'eu',
      auth: {
        headers: {
          Authorization: `Bearer ${props.authToken}`,
        },
      },
      // 添加重连配置
      reconnectTimeout: 3000, // 重连间隔(毫秒)
      reconnectAttempts: 10, // 最大重连次数
    });
    // ...后续频道订阅逻辑
  } catch (error) {
    console.log('error', error);
  }
};

2. 监听应用状态,主动触发重连

使用Expo的AppState模块监听应用从后台/休眠回到前台的事件,主动检查并恢复连接。注意用useRef持久化WebSocket实例:

import { AppState } from 'react-native';
import { useRef, useEffect } from 'react';

// 组件内声明ref保存WebSocket实例
const wsRef = useRef(null);

const connectToWebSocket = async () => {
  try {
    const ws = new Echo({
      // ...完整配置
    });
    wsRef.current = ws;
    // ...频道订阅逻辑
  } catch (error) {
    console.log('error', error);
  }
};

useEffect(() => {
  const handleAppStateChange = async (nextAppState) => {
    // 应用从后台切换到前台时触发检查
    if (nextAppState === 'active' && wsRef.current) {
      const connectionState = wsRef.current.connector.pusher.connection.state;
      // 若连接已断开,主动重连
      if (!connectionState || connectionState === 'disconnected') {
        await wsRef.current.connector.pusher.connect();
      }
    }
  };

  const subscription = AppState.addEventListener('change', handleAppStateChange);

  // 组件卸载时清理监听并断开连接
  return () => {
    subscription.remove();
    if (wsRef.current) {
      wsRef.current.disconnect();
    }
  };
}, []);

3. 优化心跳机制,避免连接被判定为闲置

调整Pusher心跳配置,让服务器和客户端及时检测连接状态,防止系统误切断:

const ws = new Echo({
  // ...其他配置
  clientConfig: {
    heartbeatInterval: 15000, // 心跳间隔(15秒)
    activityTimeout: 30000, // 连接超时时间(30秒)
  },
});

4. 处理Auth Token过期问题

设备休眠期间Auth Token可能过期,重连前需确保使用有效Token:

const refreshTokenAndReconnect = async () => {
  // 调用你的Token刷新接口
  const newToken = await fetch('/api/refresh-token', {
    method: 'POST',
    headers: { Authorization: `Bearer ${props.authToken}` }
  }).then(res => res.json()).then(data => data.token);
  
  // 更新Echo的Auth头部
  wsRef.current.connector.options.auth.headers.Authorization = `Bearer ${newToken}`;
  // 触发重连
  await wsRef.current.connector.pusher.connect();
};

// 将此方法整合到AppState状态变化逻辑中
const handleAppStateChange = async (nextAppState) => {
  if (nextAppState === 'active' && wsRef.current) {
    const connectionState = wsRef.current.connector.pusher.connection.state;
    if (!connectionState || connectionState === 'disconnected') {
      await refreshTokenAndReconnect();
    }
  }
};

5. Android前台服务(可选)

若需要应用后台也保持WebSocket连接,可使用Expo前台服务避免系统切断网络。先配置权限:

// app.json
{
  "expo": {
    "android": {
      "permissions": ["FOREGROUND_SERVICE", "WAKE_LOCK"],
      "useNextNotificationsApi": true
    }
  }
}

再通过expo-task-manager和expo-notifications实现前台服务,在服务中维持WebSocket连接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:17:43