Files
michaelschiemer/src/Application/Http/Controllers/NotificationController.php

161 lines
5.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Application\Http\Controllers;
use App\Framework\Attributes\Route;
use App\Framework\Auth\Auth;
use App\Framework\Http\Method;
use App\Framework\Http\SseStream;
use App\Framework\Http\Status;
use App\Framework\Router\Result\SseResult;
use App\Framework\Router\Result\SseResultWithCallback;
/**
* Controller für Echtzeit-Benachrichtigungen über Server-Sent Events
*/
final class NotificationController
{
/**
* Stellt einen SSE-Stream für allgemeine Benachrichtigungen bereit
*/
#[Auth]
#[Route(path: '/api/notifications/stream', method: Method::GET)]
public function notificationStream(): SseResult
{
// SSE-Result mit 3 Sekunden Retry-Intervall
$result = new SseResult(Status::OK, 3000);
// Initiale Verbindungsbestätigung
$result->addJsonEvent(
['message' => 'Verbunden mit dem Benachrichtigungsstream'],
'connected',
'conn-' . uniqid()
);
// Einige Beispiel-Benachrichtigungen beim Start senden
$result->addJsonEvent(
[
'type' => 'info',
'title' => 'Willkommen',
'message' => 'Sie sind jetzt mit Echtzeit-Updates verbunden.',
'timestamp' => time()
],
'notification',
'notif-' . uniqid()
);
return $result;
}
/**
* Stellt einen benutzer-spezifischen SSE-Stream bereit
*/
#[Auth]
#[Route(path: '/api/notifications/user/{userId}', method: Method::GET)]
public function userNotifications(int $userId): SseResult
{
// SSE-Result mit benutzerdefinierten Headern
$result = new SseResult(Status::OK, 3000, [
'X-User-ID' => (string)$userId
]);
// Verbindungsbestätigung mit Benutzer-ID
$result->addJsonEvent(
[
'message' => 'Verbunden mit dem Benutzer-Stream',
'userId' => $userId,
'timestamp' => time()
],
'connected',
'conn-user-' . $userId
);
// Aktuelle Benachrichtigungen für den Benutzer laden
$notifications = $this->getUserNotifications($userId);
// Benachrichtigungen zum Stream hinzufügen
foreach ($notifications as $notification) {
$result->addJsonEvent($notification, 'notification', $notification['id']);
}
return $result;
}
/**
* Gibt Benachrichtigungen für einen bestimmten Benutzer zurück
* In einer realen Anwendung würde diese Methode Daten aus einer Datenbank laden
*/
private function getUserNotifications(int $userId): array
{
// Beispiel-Benachrichtigungen
return [
[
'id' => 'notif-' . uniqid(),
'type' => 'message',
'title' => 'Neue Nachricht',
'message' => 'Sie haben eine neue Nachricht erhalten',
'timestamp' => time() - 300 // Vor 5 Minuten
],
[
'id' => 'notif-' . uniqid(),
'type' => 'system',
'title' => 'System-Update',
'message' => 'Das System wurde aktualisiert',
'timestamp' => time() - 3600 // Vor 1 Stunde
]
];
}
/**
* Stellt einen Live-Stream mit dynamischen Updates bereit
*/
#[Auth]
#[Route(path: '/api/notifications/live', method: Method::GET)]
public function liveNotifications(): SseResult
{
// Erweiterte SSE-Konfiguration mit Callback
#$result = new SseResultWithCallback(Status::OK, 3000);
// Callback für dynamische Updates festlegen
$callback = function(SseStream $stream) {
// Simuliere neue Benachrichtigungen (mit 10% Wahrscheinlichkeit)
if (rand(1, 10) === 1) {
$notificationTypes = ['info', 'warning', 'update', 'message'];
$type = $notificationTypes[array_rand($notificationTypes)];
$notification = [
'id' => 'live-notif-' . uniqid(),
'type' => $type,
'title' => 'Neue ' . ucfirst($type) . '-Benachrichtigung',
'message' => 'Dies ist eine dynamisch generierte Benachrichtigung vom Typ ' . $type,
'timestamp' => time()
];
$stream->sendJson($notification, 'notification', $notification['id']);
// Kleine Pause nach dem Senden, um das Testszenario zu simulieren
sleep(1);
}
};
$result = new SseResult(
retryInterval: 500,
callback: $callback,
maxDuration: 300,
heartbeatInterval: 15,
);
// Initiale Verbindungsbestätigung
$result->addJsonEvent(
['message' => 'Verbunden mit dem Live-Stream', 'timestamp' => time()],
'connected',
'live-' . uniqid()
);
return $result;
}
}