fix(net): detect a silently-dead live stream via a heartbeat watchdog #259
Reference in New Issue
Block a user
Delete Branch "feature/stream-heartbeat-watchdog"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Проблема
В простое (в игре/лобби, ничего не трогая) при включении авиарежима спиннер «Connecting…»/офлайн не появляется — в TG/VK можно ждать минутами. Появляется мгновенно только после сворачивания-разворачивания.
Корень: живой стрим (Connect server-stream поверх HTTP/2, не WebSocket) при пропаже радио умирает молча — клиенту не приходит ни FIN, ни RST, поэтому
for awaitне ошибается. Хартбит от gateway (каждые 10с) есть, но клиент по нему ставил только «онлайн», без тайм-аута на его отсутствие. Зонд вonlineне вооружён, unary-вызовов в простое нет, аnavigatoroffline в WebView TG/VK ненадёжен. Сворачивание чинит, потому чтоgoForeground()делает unary-вызовы, которые падают сразу.Что сделано (только клиент, без правок протокола/сервера)
ui/src/lib/streamwatchdog.ts: сбрасывается на каждом доставленном событии (хартбит раз в 10с держит его), при тишине ~25с считает стрим мёртвым →reportOffline+ reconnect. Фон-осведомлён (пауза наgoBackground, возобновление наgoForeground), так что троттлинг таймеров на возврате не даёт ложного офлайна.app.svelte.ts(open/onEvent/onError/close + background/foreground).docs/ARCHITECTURE.md.Порог 25с завязан на
GATEWAY_PUSH_HEARTBEAT_INTERVAL(10с) + запас; при подъёме интервала близко к порогу — риск ложных срабатываний (задокументировано).Проверка
Это PR #1 из двух; следом — офлайн-UX внутри онлайн-игры (баннер/заморозка/чат-словарь), которому этот детект — предпосылка.