diff --git a/frontend/src/lib/useSpeakRequest.ts b/frontend/src/lib/useSpeakRequest.ts index 42720fe..0bc8584 100644 --- a/frontend/src/lib/useSpeakRequest.ts +++ b/frontend/src/lib/useSpeakRequest.ts @@ -42,18 +42,41 @@ export function useSpeakRequest(token: string | undefined) { if (!token) return let cancelled = false - publicClient - .get<{ request: SpeakRequestView | null }>(`/public/participation/${token}/speak-request`) - .then((response) => { - if (!cancelled) setRequest(response.data.request) - }) - .catch(() => { - // brak stanu nie moze zablokowac wejscia na spotkanie: uczestnik - // zobaczy przycisk w stanie wyjsciowym i zglosi sie ponownie - }) + function load() { + publicClient + .get<{ request: SpeakRequestView | null }>(`/public/participation/${token}/speak-request`) + .then((response) => { + if (!cancelled) setRequest(response.data.request) + }) + .catch(() => { + // brak stanu nie moze zablokowac wejscia na spotkanie: uczestnik + // zobaczy przycisk w stanie wyjsciowym i zglosi sie ponownie + }) + } + + load() + + /* + * ODSWIEZANIE OKRESOWE JAKO SIATKA BEZPIECZENSTWA + * ------------------------------------------------------------------------- + * WebSocket zostaje glowna droga: uczestnik ma zobaczyc przyznany glos od + * razu, a nie po kilkunastu sekundach. + * + * Zdarzenie potrafi jednak nie dojsc, a polaczenie nie zawsze to + * sygnalizuje: karta uspiona przez system, chwilowa utrata sieci, + * przelaczenie z WiFi na komorke. Bez odpytywania uczestnik NIE DOWIE SIE, + * ZE MA GLOS: przycisk zostaje w starym stanie, a mikrofon zamkniety, + * chociaz uprawnienie jest juz przyznane po stronie serwera. Wyglada to na + * niedzialajacy mikrofon, a nie na zgubione zdarzenie. + * + * Odpowiedz to jeden maly obiekt albo null, wiec dziesiec sekund nie kosztuje + * nic zauwazalnego nawet przy duzej sali. + */ + const timer = window.setInterval(load, 10000) return () => { cancelled = true + window.clearInterval(timer) } }, [token]) diff --git a/frontend/src/pages/webinars/HostConsolePage.tsx b/frontend/src/pages/webinars/HostConsolePage.tsx index 73b6f5e..f30e856 100644 --- a/frontend/src/pages/webinars/HostConsolePage.tsx +++ b/frontend/src/pages/webinars/HostConsolePage.tsx @@ -127,8 +127,29 @@ export function HostConsolePage() { } }, [id]) + /* + * ODSWIEZANIE OKRESOWE JAKO SIATKA BEZPIECZENSTWA + * --------------------------------------------------------------------------- + * Kolejka odswieza sie zdarzeniem WebSocket i tak ma zostac: prowadzacy widzi + * podniesiona reke od razu, a nie po kilkunastu sekundach. + * + * Zdarzenie potrafi jednak nie dojsc, a polaczenie nie zawsze to sygnalizuje: + * karta uspiona przez system, chwilowa utrata sieci, przelaczenie WiFi na + * telefonie. Klient wznawia wtedy polaczenie, ale zdarzenia wyslanego + * w miedzyczasie nikt juz nie powtorzy, bo WebSocket nie ma historii. + * Prowadzacy widzial przez to "Nikt nie prosi o glos" przy zgloszeniach + * czekajacych juz kilka minut, i dowiadywal sie o nich dopiero po odswiezeniu + * strony. Zdarzylo sie to na zywo. + * + * Odpytywanie jest wiec DRUGA droga, nie glowna. Piec sekund jest tanie: + * kolejka to kilka wierszy, a odpowiedz przy pustej liscie wazy tyle co nic. + * Ten sam wzorzec co przy banerach na sali, gdzie front takze nie polega + * wylacznie na zdarzeniach. + */ useEffect(() => { void loadSpeakQueue() + const timer = window.setInterval(() => void loadSpeakQueue(), 5000) + return () => window.clearInterval(timer) }, [loadSpeakQueue]) const webinar = useQuery({