Envío en tiempo real con Mercure
Doggy implementa el envío en tiempo real desde el servidor basándose en el protocolo Mercure. El Mercure Hub está integrado en FrankenPHP y se habilita configurando el Caddyfile, sin necesidad de contenedores ni servicios adicionales.
Arquitectura
Cliente (EventSource)
↑ SSE
└── http://localhost:8000/.well-known/mercure
↑
Caddyfile (FrankenPHP)
↑ directiva mercure con el Hub embebido
FrankenPHP (Hub integrado)Configuración del Caddyfile
El Mercure Hub está embebido en el Caddyfile de FrankenPHP:
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
}
}
}Token JWT
MercureTokenFactory genera JWTs con permisos de suscripción:
php
// src/Security/MercureTokenFactory.php
$token = $factory->createSubscribeToken(
topics: ['/user/123/*', '/entity/*'],
roles: ['ROLE_USER'],
expiresIn: 3600
);Cookie de Mercure
MercureCookieSubscriber inyecta la cookie mercureAuthorization en cada respuesta:
php
// Temas de suscripción generados automáticamente
$topics = [
'https://enterprise.local/user/' . $userId . '/export',
'/user/' . $userId . '/*',
'/entity/*',
];Suscripción en el frontend
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);
// Procesar el mensaje recibido
};Aplicaciones principales
- Progreso de exportaciones: envío del progreso en tiempo real de exportaciones de archivos grandes
- Estado en línea:
PresenceService+PresenceApiController - Notificaciones en tiempo real: mensajes del sistema, recordatorios de aprobaciones
- Sincronización de datos: actualizaciones en tiempo real en la colaboración multi-usuario