From aba79251e0a77e923981c4d2d04ab72b8b428763 Mon Sep 17 00:00:00 2001 From: Frank Date: Sun, 16 Aug 2026 17:56:24 +0200 Subject: [PATCH] Broadcast game_finished when a player's own timeout check catches it Previously only the cron's timeout sweep broadcast to everyone; check-finished (called by a player's own client the moment their local countdown hits zero) just updated the database silently. Now whichever path notices the timeout first broadcasts - both only act while the session is still PLAYING, so there's no double broadcast. Co-Authored-By: Claude Sonnet 5 --- src/Game/Controller/GameApiController.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Game/Controller/GameApiController.php b/src/Game/Controller/GameApiController.php index 1c34eb9..a5da0af 100644 --- a/src/Game/Controller/GameApiController.php +++ b/src/Game/Controller/GameApiController.php @@ -12,6 +12,8 @@ use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Mercure\HubInterface; +use Symfony\Component\Mercure\Update; #[Route('/game/api', name: 'game_api_')] final class GameApiController extends AbstractController @@ -19,7 +21,8 @@ final class GameApiController extends AbstractController public function __construct( protected GameResponseService $gameResponseService, - private EntityManagerInterface $entityManager + private EntityManagerInterface $entityManager, + private HubInterface $hub, ) { } @@ -46,6 +49,14 @@ final class GameApiController extends AbstractController $session->setFinishedAt(new \DateTime()); $this->entityManager->persist($session); $this->entityManager->flush(); + + try { + $topic = '/game/hub/' . $session->getId(); + $this->hub->publish(new Update($topic, json_encode(['type' => 'game_finished', 'status' => 'lost']))); + } catch (\Exception $e) { + // Mercure might be down + } + $isFinished = true; } } elseif ($session->getStatus() === SessionStatus::LOST || $session->getStatus() === SessionStatus::WON) {