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 - 실시간 알림: 시스템 메시지, 승인 알림
- 데이터 동기화: 다중 사용자 협업의 실시간 업데이트