PHP 실시간 알림 미작동 문제 해결 가이드

프리터코더·2025년 6월 30일
0

php 문제 해결

목록 보기
74/79

PHP 실시간 알림 미작동 문제 해결 가이드

1. Server-Sent Events 연결 끊김

문제: SSE 연결이 자주 끊어짐

해결책: 적절한 헤더 설정과 keep-alive

header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');

while (true) {
    echo "data: " . json_encode(['message' => 'Hello']) . "\n\n";
    ob_flush();
    flush();
    sleep(5);
}

2. 세션 잠금 문제

문제: SSE 실행 중 다른 페이지 접근 불가

해결책: 세션 조기 종료

session_start();
$userId = $_SESSION['user_id'];
session_write_close(); // 세션 잠금 해제

header('Content-Type: text/event-stream');
// SSE 로직 계속...

3. 데이터베이스 폴링 과부하

문제: 실시간 확인을 위한 과도한 DB 쿼리

해결책: Redis를 이용한 pub/sub 패턴

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 알림 발송
$redis->publish('notifications', json_encode([
    'user_id' => 123,
    'message' => '새 메시지가 도착했습니다'
]));
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->subscribe(['notifications'], function($redis, $channel, $message) {
    echo "data: $message\n\n";
    ob_flush();
    flush();
});

4. 브라우저 연결 제한

문제: 브라우저당 동시 연결 수 제한

해결책: 단일 SSE 연결로 모든 알림 처리

header('Content-Type: text/event-stream');

while (true) {
    $notifications = getNotifications($userId);
    
    if (!empty($notifications)) {
        foreach ($notifications as $notification) {
            echo "data: " . json_encode($notification) . "\n\n";
        }
        ob_flush();
        flush();
    }
    
    sleep(2);
}

5. 메모리 누수

문제: 장시간 실행으로 인한 메모리 부족

해결책: 메모리 사용량 모니터링 및 제한

ini_set('memory_limit', '128M');

while (true) {
    if (memory_get_usage() > 100 * 1024 * 1024) { // 100MB
        break;
    }
    
    // 알림 처리 로직
    unset($notifications); // 변수 해제
    gc_collect_cycles();
    
    sleep(1);
}

6. 웹서버 타임아웃

문제: 웹서버에서 장시간 실행 스크립트 종료

해결책: 타임아웃 설정 조정

set_time_limit(0); // 무제한
ignore_user_abort(true); // 사용자 연결 끊어져도 계속 실행

header('Content-Type: text/event-stream');
header('X-Accel-Buffering: no'); // Nginx 버퍼링 비활성화

while (connection_status() == CONNECTION_NORMAL) {
    // 알림 로직
    sleep(1);
}

7. 중복 알림 발송

문제: 같은 알림이 여러 번 전송됨

해결책: 알림 상태 관리

function sendNotification($userId, $message) {
    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);
    
    $notificationId = uniqid();
    $key = "notification:$userId:$notificationId";
    
    if (!$redis->exists($key)) {
        $redis->setex($key, 3600, 1); // 1시간 동안 중복 방지
        
        echo "data: " . json_encode([
            'id' => $notificationId,
            'message' => $message
        ]) . "\n\n";
    }
}

8. 모바일 브라우저 호환성

문제: 모바일에서 백그라운드 시 연결 끊김

해결책: 재연결 로직 구현

function connectSSE() {
    const eventSource = new EventSource('/notifications.php');
    
    eventSource.onmessage = function(event) {
        const data = JSON.parse(event.data);
        showNotification(data.message);
    };
    
    eventSource.onerror = function() {
        eventSource.close();
        setTimeout(connectSSE, 5000); // 5초 후 재연결
    };
}

9. 푸시 알림 대안

문제: 웹 브라우저 닫힘 시 알림 불가

해결책: 웹 푸시 알림 구현

use Minishlink\WebPush\WebPush;

$webPush = new WebPush([
    'VAPID' => [
        'subject' => 'mailto:admin@example.com',
        'publicKey' => $publicKey,
        'privateKey' => $privateKey
    ]
]);

$report = $webPush->sendOneNotification(
    $subscription,
    json_encode(['title' => '새 알림', 'body' => '메시지 내용'])
);
profile
일용직 개발자. freetercoder@gmail.com

0개의 댓글