Краткий вывод
btimer представляет собой простое серверное табло: сервер считает строку времени, рассылает её всем браузерам и отдельно отправляет события звуков. fdv-bouldering-timer стал сетевым приложением для соревнований: сервер хранит единое состояние, браузеры синхронизируют свои часы с сервером, сами рассчитывают отображение и планируют звук по серверному времени.
В тексте намеренно не используются локальные пути к проектам. Для ориентира упоминаются только имена ключевых файлов: в btimer это appn.js и indexn.html, в fdv-bouldering-timer - serve-bouldering-timer.js, index.html и legacy.html.
1. Различия функциональности
| Область | btimer | fdv-bouldering-timer |
|---|---|---|
| Форматы | Фактически есть два режима: квалификация или полуфинал при заданном времени старта, и финал при пустом времени старта. Отдельных кнопок форматов нет. | Есть явные форматы Классика Фестиваль Финал. Для каждого формата свои значения по умолчанию и своя логика завершения. |
| Время старта | Поля часов и минут используются для старта квалификации или полуфинала. Если указанное время уже прошло сегодня, таймер восстанавливает состояние так, как будто он стартовал в это время. |
Есть отдельная кнопка запуска по указанному времени. Для классики и фестиваля сохранено восстановление по прошедшему времени старта. В финале обратный отсчёт до старта останавливается на 00:00 и ждёт ручного запуска.
|
| Ротация и перерыв | Вводятся время лазания в минутах и время ротации в секундах. После ротации включается красный режим ожидания, затем цикл повторяется. В финальном режиме ротация одна. | В классике задаются время ротации и перерыв в секундах. В фестивале задаются время раунда и перерыв в минутах. В финале можно задать время ротации и необязательный перерыв; после финального отрезка таймер завершается. |
| Управление |
Кнопки Start и Reset. Клавиши Z и P. Если нажать Start во время работы, btimer сначала останавливает текущий запуск и стартует заново.
|
Кнопки Старт, Пауза, Сброс, Экран, запуск по времени, полоса перемотки в паузе. Горячие клавиши Z, P, Ctrl+Q, Ctrl+F и Ctrl+M работают при английской и русской раскладке. Во время работы Старт становится неактивным.
|
| Экранные браузеры | Все подключённые браузеры получают один и тот же интерфейс и теоретически могут отправлять команды, если страница открыта. |
Есть режим основного браузера. Остальные браузеры превращаются в чистые экраны с большим таймером, без панели управления и без горячих клавиш, кроме аварийного выбора основного браузера. Отдельный экран можно переключить в Legacy-режим для старых телевизоров и браузеров; URL остаётся чистым, без видимого clientId.
|
| Защита управления | Отдельной защиты основного управляющего экрана нет: если страница доступна в сети, управление зависит от того, кто её открыл. | Основной браузер подтверждается PIN-кодом. Это снижает риск случайного или постороннего перехвата управления с другого телефона, планшета или компьютера в той же сети. |
| Синхронизация | Сервер рассылает готовую строку времени примерно раз в секунду. Браузер показывает то, что получил от сервера. |
Сервер хранит точку старта и состояние. Обычные браузеры оценивают смещение своих часов относительно сервера, получают обновления по SSE и локально считают отображаемое время. Legacy-экран использует XHR-опрос /api/state и лучшие сетевые измерения без зависимости от SSE. Диагностика показывает LEGACY, AUDIO, TIME, NET, SYNC, SSE, TAB и LIST 1–4.
|
| Плохая сеть и обрыв связи | Удалённый экран зависит от постоянной доставки обновлений от сервера. Если сеть пропала или Socket.IO-соединение перестало получать события, табло на таком экране перестанет обновляться корректно. | Браузер получает точку старта, состояние и серверное время, после чего считает отображение локально. При задержках сети табло не должно дёргаться из-за каждого пакета, а при полном временном обрыве связи уже запущенный таймер продолжит идти на экране автономно. |
| Звук | Три фиксированных MP3-сигнала: старт, минута, последние 5 секунд. Есть тестовые кнопки для каждого сигнала. События звука рассылаются сервером через Socket.IO. |
Звуковой комплект выбирается из профилей в каталоге beeps. Каждый профиль использует понятные имена START, END, MINUTE и WARNING, а также может содержать четыре фестивальных объявления. Поддерживаются WAV и MP3; если END отсутствует, используется START. Звук планируется в обычном браузере по серверному времени, есть прогрев аудио, пользовательская поправка и проверка звука на подключённых экранах. Для каждого таймера можно вручную задать задержку звука, чтобы учесть нестандартный звуковой тракт, например Bluetooth-колонку. Legacy-экран звук не воспроизводит.
|
| Голосовые сигналы | Нет голосовых объявлений. | В фестивальном формате есть голосовые объявления на русском и английском. Если голосовой движок недоступен или нет подходящего языка, используется настроенный сигнал минуты. |
| Звук на одном компьютере | Каждый браузер, получивший событие, может проиграть звук. Специальной защиты от нескольких браузеров на одном компьютере нет. | Если основной браузер и другой браузер открыты на одном компьютере, звук разрешается только из основного браузера. Это снижает риск двойного сигнала с одного устройства. |
| Полный экран | Специального управления полноэкранным режимом нет. | Есть режим Экран в основном браузере и опция полного экрана в других браузерах. Из-за правил браузеров второстепенному экрану может потребоваться тап. |
| Сеть и запуск |
Запускается через командный файл с локальным node.exe. Порт фиксирован в коде: 8008. HTTPS не предусмотрен.
|
Порты HTTP и HTTPS задаются в params.txt или переменных окружения. Есть portable-запуск для Windows, macOS и Linux с bundled Node.js, поддержка PEM-сертификатов, генерация сертификата и отдельные настраиваемые пути к Node.js для каждой ОС. Приложение сервера позволяет запускать и перезапускать сервер, видеть все доступные ссылки для подключения и копировать их. Для macOS в документации добавлены команды снятия quarantine-атрибута с приложения сервера или всей распакованной папки.
|
| Перезапуск сервера | Состояние текущего отсчёта держится в процессе сервера. При краше или незапланированном перезапуске удалённые экраны зависят от того, когда восстановится соединение и какие новые события придут от сервера. | Уже открытые браузеры продолжают показывать запущенный таймер автономно. После перезапуска сервер восстанавливает сохранённое состояние и продолжает прерванный отсчёт, а не начинает его заново с исходного значения. |
| Настройки | Настройки вводятся на странице перед стартом. Конфигурационного файла нет. |
Начальные значения задаются в params.txt: порты, длительности, язык, чекбоксы и звуковой профиль. Изменения параметров во время работы не ломают текущий запуск и применяются после перезапуска таймера.
|
| Язык и справка | Интерфейс старой страницы в основном английский, подробной встроенной справки нет. |
Интерфейс переключается между русским и английским, есть подробное руководство help.html и краткий ReadMe.txt.
|
| Стартовые списки и трассы | Отдельных синхронизируемых стартовых списков, импорта таблиц и управления инцидентами трасс нет. | До четырёх LIST импортируются из XLSX, CSV, TSV, TXT и MXL. Каждый экран выбирает свой набор LIST и раскладку двух списков. Есть подготовка/лазание/завершение, автопрокрутка, исключение участника, а также приостановка, возобновление и остановка трассы по ротациям с управляемой остановкой всей волны. |
| Наблюдаемость и эксплуатация | Нет единой панели качества сети, синхронизации, аудио и состояния вкладок. | Плашки LEGACY, AUDIO, TIME, NET, SYNC, SSE, TAB и LIST 1–4 показывают доступность и проблему каждого экрана. Карточки браузеров можно закреплять и переставлять; на трёх и более экранах включаются диагностические номера. |
| Автономность и установка | Работа предполагает локальный сервер и открытие страницы в браузере. | Кроме сетевого таймера есть однофайловый автономный вариант для любой ОС и APK FDV Bouldering Timer для Android. APK намеренно работает на одном устройстве без сервера и сетевых экранов. Установочные файлы для Windows, macOS, Linux и Android доступны также через Komi Store. |
| HTTPS и возможности браузера | HTTPS и защищённый контекст не предусмотрены. | HTTPS с локальным сертификатом сохраняет все функции HTTP и дополнительно открывает защищённый контекст: Wake Lock на поддерживаемых устройствах, сервис-воркер для повторного открытия кэшированной страницы и современный API буфера обмена. Звук и полный экран всё равно требуют пользовательского жеста. |
2. Различия архитектурного подхода
btimer
appn.js запускает Express и Socket.IO, хранит глобальные переменные старта, длительности, режима и каждые 200 мс пересчитывает текущее состояние.
timer со строкой вроде 3:42 и режимом отображения. Клиент почти не вычисляет время сам.
playStart, playMin или playGong. Браузер сразу вызывает проигрывание MP3.
fdv-bouldering-timer
serve-bouldering-timer.js хранит активный формат, настройки, точку старта, паузы, финальное завершение, список браузеров и их диагностику.
index.html получает состояние и время сервера, оценивает сетевую задержку и смещение часов, затем сам рассчитывает отображаемые секунды.
legacy.html показывает только крупное табло, использует упрощённый JavaScript, XHR-опрос /api/state, не требует SSE, Fetch API, Web Audio и Wake Lock, автоматически подбирает размер цифр для телефонов и старых телевизоров.
/api/events. Параллельно браузер периодически сверяется через /api/state, чтобы восстановиться после сна, потери связи или открытия новой вкладки.
beeps, сопоставляет стандартные роли файлов и включает выбранный профиль в общее состояние. Все браузеры получают одинаковые адреса сигналов, заранее знают серверное время их воспроизведения и планируют Web Audio на локальной шкале. Для каждого таймера можно задать пользовательскую поправку звука, например компенсировать задержку Bluetooth-колонки или другого нестандартного звукового тракта.
Почему новая архитектура сложнее
fdv-bouldering-timer должен одинаково выглядеть в нескольких браузерах, переживать открытие новых экранов, сон телефона, сетевые задержки, временный обрыв связи, перезапуск сервера, разные браузерные ограничения звука, старые браузеры телевизоров и разные сценарии соревнований. Поэтому в нём появились роли браузеров, PIN основного браузера, диагностика, синхронизация часов, SSE, Legacy-страница с XHR, параметры запуска, HTTPS, приложение сервера, обнаружение звуковых профилей и отдельная логика звукового планирования.
Что осталось принципиально похожим
- Обе версии запускают локальный веб-сервер и открываются в браузере.
- Обе версии используют сервер как источник общего состояния соревнования.
- Обе версии поддерживают стартовый сигнал, сигнал за минуту и сигналы последних пяти секунд.
- Обе версии умеют работать с несколькими браузерами, но fdv-bouldering-timer делает это как отдельную управляемую функцию.
Что важно для практического использования
btimer хорош своей прямотой: меньше кода, меньше настроек, быстрее понять внутреннюю механику. fdv-bouldering-timer лучше подходит для реального зала с несколькими экранами: он даёт контроль над тем, кто управляет таймером через PIN, кто воспроизводит звук, какой звуковой комплект используется, нужна ли ручная задержка звука для конкретного таймера, насколько хорошо синхронизированы браузеры, какие адреса доступны по сети, что происходит при потере связи или перезапуске сервера и какие старые устройства стоит перевести на Legacy-экран.
Архитектурно btimer ближе к модели “сервер рисует табло через события”. fdv-bouldering-timer ближе к модели “сервер задаёт точное время и состояние, а браузеры синхронно воспроизводят это состояние локально, постоянно сверяя время с сервером”. Именно это отличие объясняет большую часть новых возможностей и большую сложность кода.