Skip to content

Mercure 실시간 푸시

Doggy는 Mercure 프로토콜 기반 서버 실시간 푸시를 구현합니다. Mercure Hub는 FrankenPHP에 내장되어 Caddyfile 설정만으로 활성화할 수 있으며 별도의 컨테이너나 서비스가 필요 없습니다.

아키텍처

클라이언트 (EventSource)
    ↑ SSE
    └── http://localhost:8000/.well-known/mercure

    Caddyfile (FrankenPHP)
        ↑ mercure 지시문에 Hub 내장
    FrankenPHP (내장 Hub)

Caddyfile 설정

FrankenPHP의 Caddyfile에 Mercure Hub를 내장합니다:

caddy
http://localhost:8000 {
    route /.well-known/mercure {
        mercure {
            transport bolt {
                path /var/www/var/mercure.db
            }
            publisher_jwt !ChangeThisMercureHubJWTSecretKey!
            subscriber_jwt !ChangeThisMercureHubJWTSecretKey!
            cors_origins http://localhost:8000
            publish_origins *
            anonymous
        }
    }
}

JWT 토큰

MercureTokenFactory가 구독 권한이 포함된 JWT를 생성합니다:

php
// src/Security/MercureTokenFactory.php
$token = $factory->createSubscribeToken(
    topics: ['/user/123/*', '/entity/*'],
    roles: ['ROLE_USER'],
    expiresIn: 3600
);

Mercure 쿠키

MercureCookieSubscriber가 각 응답에 mercureAuthorization 쿠키를 주입합니다:

php
// 자동 생성된 구독 토픽
$topics = [
    'https://enterprise.local/user/' . $userId . '/export',
    '/user/' . $userId . '/*',
    '/entity/*',
];

프론트엔드 구독

javascript
const url = new URL('/.well-known/mercure', window.location.origin);
url.searchParams.append('topic', '/user/' + userId + '/*');
const eventSource = new EventSource(url);
eventSource.onmessage = (event) => {
    const data = JSON.parse(event.data);
    // 푸시 메시지 처리
};

핵심 응용

  • 내보내기 진행률: 대용량 파일 내보내기의 실시간 진행률 푸시
  • 온라인 상태: PresenceService + PresenceApiController
  • 실시간 알림: 시스템 메시지, 승인 알림
  • 데이터 동기화: 다중 사용자 협업의 실시간 업데이트

MIT 라이선스 오픈소스 | Copyright © 2026 Doggy