Обзор — что это даёт
Панели InfraGuard обновляются сами, без перезагрузки страницы. Это автообновление опирается на два механизма.
| Механизм | Как | Задержка | Кто использует |
|---|---|---|---|
| WebSocket Reverb | Сервер → браузер, мгновенная отправка (событийная модель) | миллисекунды | живые задания, транслирующие прогресс в виде тиков |
| Лёгкий опрос | Браузер с интервалом выполняет GET /…/live |
до 30 с | большинство панелей (Состояние, Серверы, Трафик, Сервисы, Безопасность, Оповещения …) |
Всё это сводится к одному принципу проектирования:
Живое обновление — это надстройка поверх сохранённых данных. Каждый экран сначала отрисовывает данные, сохранённые в БД, а обновления в реальном времени ложатся сверху. Поэтому даже если Reverb (сервер WebSocket) выключен, заблокирован межсетевым экраном или перезапускается, экран никогда не ломается. Когда push недоступен, его подменяет опрос (плавная деградация).
На практике почти каждый экран работает на опросе. WebSocket Reverb установлен и подключён, и сегодня он обслуживает ровно одну функцию — удалённую эмуляцию диагностики безопасности (Удалённая эмуляция · Диагностика безопасности), где транслирует тики прогресса по каждому хосту. Все остальные живые экраны обновляются 30-секундным опросом плюс дешёвым токеном обнаружения изменений rev.
Когда это применять
Это концептуальный справочник. Это не экран с живым маршрутом — материал предназначен для операторов и инженеров, которые хотят понять:
- как панели сами поддерживают себя в актуальном состоянии
- что происходит в средах, где WebSocket не может подключиться (внутренние сети, прокси, смешанный контент)
- как опрос экономит заряд батареи и нагрузку на сервер (он приостанавливается, когда вкладка уходит в фон)
Устройство экрана
Архитектура из двух путей
[сохранённые данные] server_status · infr_db_metric · blacklist_info · …
│
▼ (первая загрузка страницы: сервер встраивает JSON data-* в представление)
[экран браузера] ← отрисовывается мгновенно (полноценен и без живого обновления)
▲ ▲
│ (A) опрос │ (B) push от Reverb
│ GET /…/live (≤30s) │ событие WS 'tick'
│ перерисовка только rev↑ │ ShouldBroadcastNow
[контроллер Laravel] [сервер Reverb]
- (A) Опрос — фронтенд вызывает
/{screen}/liveкаждые 30 секунд черезsetInterval. Ответ несёт дешёвый токен измененийrev; графики и карточки перерисовываются только при его изменении. Если вкладка ушла в фон (document.hidden), вызов пропускается. - (B) Push от Reverb — сервер немедленно рассылает событие (
ShouldBroadcastNow— без очереди), и подписанные браузеры получают его по WebSocket. Сегодня это используется исключительно для тиков прогресса удалённой эмуляции.
Топология Reverb
| Элемент | Значение | Источник |
|---|---|---|
| Клиентские библиотеки | laravel-echo + pusher-js |
динамический импорт (исключены из основного бандла) |
Параметры подключения WebSocket настраиваются при установке. Оператору достаточно открыть экран — настраивать нечего.
Как пользоваться
Операторам — делать ничего не нужно
Живое обновление работает автоматически. Оставьте экран открытым, и опрос будет забирать свежие значения каждые 30 секунд; если WebSocket включён, событийные экраны обновляются мгновенно. Ради экономии энергии опрос приостанавливается, пока вкладка находится в фоне, и возобновляется, когда вы к ней возвращаетесь.
Включение WebSocket Reverb (необязательно)
Push по WebSocket настраивает ваш ответственный за развёртывание во время установки — это не переключатель для оператора в консоли. Если вам нужен push в реальном времени, обратитесь к администратору или к поставщику.
Выключенный push по WebSocket — не ошибка. Это намеренный выключатель: живые экраны продолжают работать на одном лишь опросе.
Что на самом деле делает опрос
// Характерный шаблон (например, service-overview)
poll_ms: 30000,
this._poll = setInterval(() => {
if (this.live && !document.hidden) this.poll_tick(); // пропустить, если вкладка в фоне
}, this.poll_ms);
// poll_tick → GET /service/live → перерисовка только при изменении rev в ответе
Серверный rev — это максимально дешёвый сигнал изменения. Например, экран серверных метрик использует в качестве rev значение MAX(seq) из устаревшей таблицы server_status: оно растёт только тогда, когда коллектор вставляет новый снимок.
// App\Services\Metric\ServerMetricService::rev()
return (int) DB::connection('legacy')->table('server_status')->max('seq');
Единственное живое задание, использующее push Reverb, — удалённая эмуляция
Удалённая эмуляция из раздела Диагностика безопасности рассылает тик прогресса каждый раз, когда очередной хост завершает работу.
- Событие:
App\Events\InfrRemoteEmulateTick(ShouldBroadcastNow) - Канал: публичный канал
infr.emulate.{runId}—runIdпредставляет собой неугадываемый случайный токен (мандат доступа). Поскольку канал публичный, ему не нужна сессионная обвязка/broadcasting/auth. - Имя события:
.tick· полезная нагрузка лёгкая (только сводка по хосту и счётчики прогресса) - Запасной путь: фронтенд подписывается на канал и одновременно выполняет резервный опрос раз в 2 секунды (
/asset/remote/emulate-status/{runId}), поэтому прогресс не теряется, даже если WS отсутствует или ранний тик был пропущен.
Источники данных
| Файл | Роль |
|---|---|
resources/js/echo.js |
Единственный сборщик Echo в приложении (SOT) — динамический импорт · проверка конфигурации → null · forceTLS во время выполнения |
app/Support/Realtime.php |
Страховка для рассылки (проба fsockopen в up() · поглотитель исключений в fire()) |
routes/channels.php |
Колбэки авторизации каналов (сейчас только стандартный App.Models.User.{id}) |
app/Events/InfrRemoteEmulateTick.php |
Единственное реально используемое событие рассылки |
контроллер …/live каждого экрана + …Service::rev() |
живая полезная нагрузка для опроса + токен изменений |
Realtime — двухслойная защита (WS может умереть, не утянув за собой исходную работу)
// (1) up() — проба fsockopen с таймаутом 150 мс (мемоизируется на запрос). Метод broadcastWhen() события опирается на неё,
// поэтому при недоступном Reverb событие ShouldBroadcastNow НЕ выбрасывает исключение по таймауту соединения прямо в коде.
public static function up(): bool // пробует по конфигурации (без жёстко зашитых значений)
// (2) fire() — защищает вызывающий код даже тогда, когда Reverb работает, но отклоняет запрос (413 либо 5xx во время перезапуска).
// Сбои отправляются через report() в Pulse Exceptions; исходная работа (сохранённый результат сканирования) всё равно завершается успешно.
public static function fire(object $event): void
Метод broadcastWhen() события возвращает Realtime::up() — если Reverb выключен, отправка пропускается полностью.
Права доступа
Авторизация каналов
| Тип канала | Аутентификация |
|---|---|
Публичный канал (infr.emulate.{runId}) |
нет — токен-мандат runId сам по себе и есть разрешение на доступ (его невозможно угадать) |
| каналы private / presence (план развития) | колбэк в routes/channels.php проверяет user_level сессии + область роли |
Таблица каналов реального времени в CLAUDE.md (
private-infr.server.{id},private-infr.threats,presence-infr.ops, …) — это план развития. Реализованная сегодня рассылка представляет собой единственный публичный каналinfr.emulate.{runId}, аroutes/channels.phpрегистрирует лишь приватный каналApp.Models.User.{id}, заданный фреймворком по умолчанию. Когда появятся каналы private/presence, всегда авторизуйте поuser_levelи области (например,infr.threatsтребуетuser_level>=2 && scope∋security).
Доступ к конечным точкам опроса
Конечные точки опроса /{screen}/live наследуют проверку уровня чтения контроллера своего экрана (demo=1, staff=5, admin=10; некоторые разделы закрыты посредником infr.level:N). Например, резервный опрос состояния удалённой эмуляции (emulate-status) требует доступа на запись (уровень ≥2). Полная политика описана в разделе Уровни RBAC.
Устранение неполадок и частые вопросы
В. WebSocket не подключается, но экран продолжает обновляться?
Так и задумано. Живые экраны полностью работоспособны на опросе и без WS. WebSocket лишь сокращает задержку для событийных заданий вроде удалённой эмуляции.
В. Я включил Reverb, но браузер не подключается
- Смешанный контент —
echo.jsопределяетforceTLSпо протоколу страницы во время выполнения (wss, если страница открыта поhttps:). Он намеренно не берёт это значение из переменной сборки: так исключается ситуация, когда бандл, отданный по https, пытается открытьws://и блокируется браузером. Если фронтенд работает по https, то и Reverb должен отдавать TLS (wss) либо TLS должен терминировать прокси. - CSP / CORS —
echo.jsзадаётenabledTransports: ['ws','wss']+disableStats: true, чтобы заблокировать резервный CDN sockjs в pusher-js и отправку статистики (они нарушили бы CSP при развёртывании на собственной инфраструктуре).
В. Не создаёт ли панель чрезмерную нагрузку на сервер и БД?
- Интервал опроса — 30 секунд, и он останавливается, когда вкладка уходит в фон (
document.hidden). - Токен изменений
rev(например,MAX(seq)) позволяет пропускать тяжёлую перерисовку, когда новых данных нет. - Сервисы, собирающие живые данные, в большинстве своём кешируются на 20–30 секунд.
В. Можно ли запускать демоны реального времени через планировщик?
Ни в коем случае. Не запускайте из планировщика (
Schedule::command(...)) демоны с бесконечным циклом, такие какreverb:start,queue:workилиpulse:check. Процессы, которые никогда не завершаются, накапливаются на каждом тике и исчерпывают общий пул подключений MySQL (замерено 2026-08-06 наpulse:check: 169 накопленных процессов за 16 часов →[1040] Too many connections, с влиянием на промышленную БД). Запускайте демоны только из единственной постоянной панели лаунчера (разработка) либо через supervisor/systemd (продуктив). О размещении демонов см. Разработка · Наблюдаемость.
В. Как перезапустить Reverb после изменения кода?
В продуктиве — php artisan reverb:restart без простоя (либо перезапустите его под supervisor). В разработке перезапустите панель лаунчера. Если во время перезапуска WS ненадолго начнёт отклонять подключения, Realtime::fire() поглотит исключение, а опрос закроет паузу.
Смежные материалы
- Удалённая эмуляция — единственное живое задание, которое действительно использует push Reverb
- Диагностика безопасности — экран, через который проходят тики прогресса удалённой эмуляции
- Разработка · Наблюдаемость (Pulse) — дисциплина запуска демонов · куда попадают исключения Realtime
- Инфраструктура ▸ Серверы — канонический пример 30-секундного опроса + rev-токена
MAX(seq) - Обзор сервисов — шаблон опроса живой доски
- Уровни RBAC — проверки доступа для каналов и конечных точек опроса
