0007. Поток событий вместо веб-сокета¶
Дата: август 2026. Состояние: принято.
Контекст¶
Браузеру нужно получать положение составов раз в секунду. Связь односторонняя: браузер ничего не отправляет обратно — управление сценариями идёт обычными запросами.
Варианты: веб-сокет, поток событий сервера (SSE), периодический опрос.
Решение¶
Поток событий сервера. Приложение открывает text/event-stream и раз в секунду
рассылает кадр всем подписчикам.
Три существенные детали:
Кадр сериализуется один раз для всех подписчиков. Сериализация на каждого была бы самой дорогой операцией: четыреста составов на сотню подписчиков — сто проходов по одним и тем же данным.
Сжатие для потока отключено. Буферизация сжатия задерживает кадр, и карта начинает дёргаться без всякой деградации сервиса. Остальные ответы сжимаются.
Таймаут асинхронного запроса снят. Стандартный таймаут Spring MVC обрывал бы долгоживущее соединение через тридцать секунд.
Последствия¶
Что получили. Простоту. Поток событий — это обычный ответ HTTP: он проходит
через Traefik без отдельной настройки обновления протокола, работает через прокси
и корпоративные фильтры, а браузер сам переподключается при обрыве. Никакой
библиотеки на стороне клиента: EventSource встроен в браузер.
Виртуальные потоки Java 21 делают такую модель дешёвой: соединение, которое почти всё время ждёт, занимает сотни байт вместо мегабайта стека.
Чем заплатили. Канал односторонний. Если бы понадобилось отправлять что-то от браузера в том же соединении — например интерактивную подписку на отдельную линию, — пришлось бы переходить на веб-сокет.
Ограничение числа соединений на домен в старых браузерах — шесть на HTTP/1.1. Стенд работает по HTTP/2, где это ограничение не действует, но на HTTP/1.1 несколько открытых вкладок могли бы упереться в предел.
Что рассматривалось¶
Веб-сокет — даёт двустороннюю связь, которая здесь не нужна, и требует настройки обновления протокола на входном прокси, отдельной обработки переподключения и библиотеки на клиенте.
Опрос раз в секунду — самое простое и худшее: на каждый кадр новое соединение, заголовки, установка TLS. При сотне посетителей это в разы больше работы, чем одно долгоживущее соединение.
Опрос раз в пять секунд с интерполяцией — сэкономил бы соединения, но положение поездов расходилось бы с расчётным на несколько секунд, и на схеме это заметно: состав «телепортируется» при каждом обновлении.