React Native 앱 백그라운드 상태 처리와 AppState API
문제 상황
회사 메신저 앱에서 사용자가 앱을 백그라운드로 전환했다가 돌아오면 WebSocket 연결이 끊어진 채로 유지되는 이슈가 발생했다. iOS에서는 백그라운드 진입 후 약 30초 뒤 연결이 끊기고, Android에서는 절전 모드에서 불규칙하게 끊겼다.
AppState API 활용
React Native의 AppState API를 사용해 앱의 상태 변화를 감지했다.
import { AppState } from 'react-native';
import { useEffect, useRef } from 'react';
const ChatScreen = () => {
const appState = useRef(AppState.currentState);
const reconnectTimeoutRef = useRef(null);
useEffect(() => {
const subscription = AppState.addEventListener('change', nextAppState => {
if (
appState.current.match(/inactive|background/) &&
nextAppState === 'active'
) {
// 포어그라운드 복귀 시 재연결
handleReconnect();
}
if (nextAppState === 'background') {
// 백그라운드 진입 시 타임아웃 설정
reconnectTimeoutRef.current = setTimeout(() => {
socket.disconnect();
}, 25000);
}
appState.current = nextAppState;
});
return () => {
subscription.remove();
if (reconnectTimeoutRef.current) {
clearTimeout(reconnectTimeoutRef.current);
}
};
}, []);
const handleReconnect = () => {
if (reconnectTimeoutRef.current) {
clearTimeout(reconnectTimeoutRef.current);
}
if (!socket.connected) {
socket.connect();
}
};
return (/* ... */);
};
추가 고려사항
백그라운드에서 완전히 종료되기 전에 미리 연결을 끊어 배터리를 절약하도록 했다. iOS의 경우 백그라운드 실행 시간이 제한적이므로 25초 정도에 타임아웃을 설정했다.
Android에서는 react-native-background-timer를 추가로 사용해 더 정확한 타이밍 제어가 가능했지만, 일단은 기본 API만으로 처리했다.
결과
포어그라운드 복귀 시 자동 재연결이 안정적으로 동작하고, 불필요한 백그라운드 연결 유지로 인한 배터리 소모도 줄었다. 다음에는 네트워크 상태 변화도 함께 감지하는 로직을 추가할 예정이다.