Files
stream.graff.tech-new/session-server/README.md
T

20 KiB
Raw Blame History

Session Server

Сессионный сервер для автоматической регистрации на основном API сервере.

Описание

Session Server - это приложение, которое автоматически регистрируется на основном сервере (stream.graff.tech) и периодически обновляет свою информацию. Это позволяет основному серверу знать о доступных сессионных серверах для распределения нагрузки.

Возможности

  • 🚀 Автоматическая регистрация при запуске
  • 🔄 Периодическое обновление информации о сервере (по умолчанию каждые 30 секунд после завершения предыдущего запроса)
  • 🎮 Автоматическое определение и обновление свободной GPU памяти через nvidia-smi (по умолчанию каждую секунду после завершения предыдущего запроса)
  • 🎯 Автоматическое управление игровыми сессиями
    • Запуск приложений для сессий со статусом "starting"
    • Остановка приложений для сессий со статусом "ending"
    • Отслеживание PID запущенных процессов
    • Автоматическое обновление статусов сессий на главном сервере
  • 🌐 Автоматическое определение локального IP адреса
  • 💻 Автоматическое определение hostname
  • ⚙️ Гибкая конфигурация через переменные окружения
  • 🔁 Автоматические повторные попытки при ошибках
  • 📝 Подробное логирование
  • Защита от наложения запросов для всех операций (рекурсивный вызов через setTimeout)

Установка

# Установка зависимостей
bun install

Конфигурация

Создайте файл .env в корне проекта на основе .env.example:

# URL основного API сервера
API_URL=http://localhost:3000

# Тип сервера: stream или local
SERVER_TYPE=stream

# Расположение сервера (ОБЯЗАТЕЛЬНО для stream серверов)
# Возможные значения: ru1, uae1
SERVER_LOCATION=ru1

# Уровень сервера (только для stream серверов)
# Возможные значения: demo, prod
SERVER_TIER=demo

# ID филиала (ОБЯЗАТЕЛЬНО для local серверов)
BRANCH_ID=00000000-0000-0000-0000-000000000000

# Локальный IP адрес (опционально, определяется автоматически)
# LOCAL_IP=192.168.1.100

# Hostname сервера (опционально, определяется автоматически)
# HOSTNAME=my-session-server

# Интервал регистрации в миллисекундах (по умолчанию 30000 = 30 секунд)
REGISTER_INTERVAL_MS=30000

# Интервал обновления GPU памяти в миллисекундах (по умолчанию 1000 = 1 секунда)
GPU_UPDATE_INTERVAL_MS=1000

# Интервал проверки сессий в миллисекундах (по умолчанию 5000 = 5 секунд)
SESSION_CHECK_INTERVAL_MS=5000

Переменные окружения

Переменная Описание Обязательна По умолчанию
API_URL URL основного API сервера Нет http://localhost:3000
SERVER_TYPE Тип сервера (stream или local) Нет stream
SERVER_LOCATION Расположение (ru1, uae1) - обязательно для stream Да (для stream) -
SERVER_TIER Уровень (demo, prod) - только для stream Нет demo (для stream)
BRANCH_ID ID филиала - обязательно для local Да (для local) -
LOCAL_IP Локальный IP адрес Нет Определяется автоматически
HOSTNAME Hostname сервера Нет Определяется автоматически
REGISTER_INTERVAL_MS Интервал регистрации в мс Нет 30000
GPU_UPDATE_INTERVAL_MS Интервал обновления GPU памяти в мс Нет 1000
SESSION_CHECK_INTERVAL_MS Интервал проверки сессий в мс Нет 5000

Примечание: Свободная память GPU (gpuFreeMb) автоматически определяется через nvidia-smi при каждой регистрации и обновляется каждую секунду (или согласно GPU_UPDATE_INTERVAL_MS) после завершения предыдущего запроса. Это предотвращает наложение запросов. Если nvidia-smi недоступен, сервер завершит работу с ошибкой.

Управление сессиями

Session Server автоматически управляет игровыми сессиями на этом сервере:

Как это работает

  1. Проверка сессий: Каждую секунду (или согласно SESSION_CHECK_INTERVAL_MS) сервер запрашивает у основного API список сессий для этого сервера
  2. Запуск приложений: Для сессий со статусом starting:
    • Проверяется время startAt - приложение запускается только если это время уже наступило
    • Timezone: Все время хранится в UTC, сравнение корректно работает независимо от часового пояса сервера
    • Запланированные сессии (с будущим startAt) логируются с информацией о времени до запуска
    • 🎯 Централизованное назначение сервера (для stream-сессий):
      • Main server автоматически назначает серверы каждые 5 секунд
      • Выбирается сервер с максимальной свободной GPU памятью
      • Учитываются требования приложения к GPU памяти (gpuLimitMb)
      • Session-server просто проверяет, что сессия назначена ему
    • Запускается соответствующее приложение
    • Отслеживается PID процесса
    • Статус сессии обновляется на started на главном сервере
  3. Остановка приложений: Для сессий со статусом ending:
    • Используется taskkill /pid {PID} /T /F для завершения всего дерева процессов
    • /T - завершает указанный процесс и ВСЕ дочерние процессы
    • /F - принудительное завершение
    • Решает проблему с UE5 и другими приложениями, создающими дочерние процессы
    • Статус сессии обновляется на ended на главном сервере
  4. Автоматическая очистка: Процессы для неактивных сессий автоматически останавливаются

API endpoints для управления сессиями

Session Server взаимодействует с основным сервером через следующие endpoints:

  • GET /servers/:id/sessions - получить список сессий для сервера
  • PATCH /sessions/:id/status - обновить статус сессии (публичный endpoint)

Запуск приложений

Session Server автоматически запускает .exe приложения по стандартному пути:

C:\apps\{appName}\{appName}.exe

Где {appName} - это значение поля name из таблицы apps.

Структура директорий

Все приложения должны быть размещены в следующей структуре:

C:\apps\
├── minecraft\
│   └── minecraft.exe
├── fortnite\
│   └── fortnite.exe
└── cyberpunk\
    └── cyberpunk.exe

Особенности запуска и остановки

  • Автоматическая проверка существования exe файла
  • Рабочая директория устанавливается в папку приложения (C:\apps\{appName}\)
  • Окно консоли скрывается (windowsHide: true)
  • PID процесса отслеживается и передается на main server
  • Автоматическое обновление статуса при завершении процесса
  • Корректное завершение дочерних процессов - использует taskkill /T для завершения всего дерева процессов
  • Решает проблему с UE5 приложениями, которые создают множественные процессы

Логи запуска

[2025-10-06T10:00:00.000Z] 🚀 Запуск приложения "minecraft" для сессии abc-123
[2025-10-06T10:00:00.050Z] 📂 Путь к приложению: C:\apps\minecraft\minecraft.exe
[2025-10-06T10:00:01.000Z] ✅ Приложение запущено с PID 12345
[2025-10-06T10:00:01.100Z] ✅ Статус сессии abc-123 обновлен на "started"

Обработка ошибок

Если exe файл не найден:

❌ Файл приложения не найден: C:\apps\minecraft\minecraft.exe. Убедитесь, что приложение установлено.

Примеры логов

Запланированная сессия:

[2025-10-06T10:00:00.000Z] ⏰ Сессия 123e4567-e89b-12d3-a456-426614174000 (minecraft) запланирована через 120 сек

Запуск сессии:

[2025-10-06T10:02:00.000Z] 🚀 Запуск приложения "minecraft" для сессии 123e4567-e89b-12d3-a456-426614174000
[2025-10-06T10:02:01.000Z] ✅ Приложение запущено с PID 12345
[2025-10-06T10:02:01.100Z] ✅ Статус сессии 123e4567-e89b-12d3-a456-426614174000 обновлен на "started"

Остановка сессии:

[2025-10-06T10:32:00.000Z] 🛑 Остановка приложения для сессии 123e4567-e89b-12d3-a456-426614174000 (PID: 12345)
[2025-10-06T10:32:00.500Z] ✅ Дерево процессов для PID 12345 успешно завершено
[2025-10-06T10:32:00.600Z] ✅ Приложение и все дочерние процессы остановлены для сессии 123e4567-e89b-12d3-a456-426614174000
[2025-10-06T10:32:00.700Z] ✅ Статус сессии 123e4567-e89b-12d3-a456-426614174000 обновлен на "ended"

Отладка проблем (Troubleshooting)

Если приложение запускается и сразу завершается с ошибкой, см. подробное руководство по диагностике:

Новые возможности логирования

После обновления вы увидите:

  • 🔴 STDERR логи для диагностики ошибок приложений
  • 📊 Счётчик активных процессов при запуске/завершении
  • ⚠️ Детальная информация о кодах выхода и сигналах

Пример логов с ошибкой:

[10:51:56.498Z] 🚀 Запуск приложения "ShishimGorka" для сессии abc (активных процессов: 1)
[10:51:56.563Z] ✅ Приложение запущено с PID 84112 (всего активных: 2)
[10:51:57.500Z] 🔴 STDERR [abc]: Error: Port 8888 is already in use
[10:51:57.894Z] 🛑 Приложение для сессии abc завершилось с кодом 1
[10:51:57.894Z] ⚠️ Приложение завершилось с ошибкой! Код выхода: 1

Работа с часовыми поясами (Timezone)

Session Server корректно работает с разными часовыми поясами:

Как это работает

  1. База данных: PostgreSQL хранит все timestamp с timezone в UTC
  2. API: Основной сервер возвращает время в формате ISO 8601 с timezone (например, 2025-10-06T10:00:00.000Z)
  3. Session Server: JavaScript автоматически парсит ISO 8601 строки в UTC
  4. Сравнение: Все сравнения времени происходят в UTC, независимо от локального часового пояса сервера

Миграция базы данных

⚠️ Важно: Если вы обновляете существующую систему, необходимо выполнить миграцию для добавления timezone в поля startAt и endAt:

# Из директории server/
psql -d $DATABASE_URL -f timezone_migration.sql

См. server/TIMEZONE_MIGRATION.md для подробностей.

Примеры

Если сервер в России создаёт сессию на 14:00 по московскому времени (UTC+3):

  • В БД сохранится: 2025-10-06T11:00:00.000Z (UTC)
  • Сервер в ОАЭ (UTC+4) увидит: 15:00 по местному времени
  • Session Server запустит приложение ровно в 11:00 UTC, независимо от локального времени

Запуск

Development режим

bun run dev

Production режим

# Собрать проект
bun run build

# Запустить собранное приложение
bun run start

Примеры использования

Stream сервер в России (демо)

API_URL=https://api.stream.graff.tech
SERVER_TYPE=stream
SERVER_LOCATION=ru1
SERVER_TIER=demo
REGISTER_INTERVAL_MS=30000

Stream сервер в ОАЭ (продакшн)

API_URL=https://api.stream.graff.tech
SERVER_TYPE=stream
SERVER_LOCATION=uae1
SERVER_TIER=prod
REGISTER_INTERVAL_MS=30000

Local сервер для филиала

API_URL=https://api.stream.graff.tech
SERVER_TYPE=local
BRANCH_ID=123e4567-e89b-12d3-a456-426614174000
REGISTER_INTERVAL_MS=60000

Логирование

Сервер выводит подробную информацию о своей работе:

============================================================
🚀 Запуск сессионного сервера
============================================================
Конфигурация:
  API URL: http://localhost:3000
  Hostname: DESKTOP-ABC123
  Local IP: 192.168.1.100
  Type: stream
  GPU Free MB: 8192 (читается из nvidia-smi)
  Location: ru1
  Tier: demo
  Register Interval: 30000ms
  GPU Update Interval: 1000ms
============================================================
[2025-10-06T12:00:00.000Z] Регистрация сервера...
Данные: {
  "localIp": "192.168.1.100",
  "hostname": "DESKTOP-ABC123",
  "type": "stream",
  "gpuFreeMb": 8192,
  "location": "ru1",
  "tier": "demo"
}
[2025-10-06T12:00:00.123Z] ✅ Сервер успешно зарегистрирован
ID сервера: 123e4567-e89b-12d3-a456-426614174000
[2025-10-06T12:00:01.000Z] 🎮 GPU память обновлена: 8150 MB
[2025-10-06T12:00:02.000Z] 🎮 GPU память обновлена: 8120 MB
[2025-10-06T12:00:03.000Z] 🎮 GPU память обновлена: 8100 MB

Обработка ошибок

Сервер автоматически обрабатывает ошибки:

  • Валидация конфигурации:
    • Stream-серверы: обязательно должен быть указан SERVER_LOCATION
    • Local-серверы: обязательно должен быть указан BRANCH_ID
    • При отсутствии обязательных полей сервер завершит работу с критической ошибкой
  • Сетевые ошибки: Автоматические повторные попытки (до 3 раз)
  • Таймауты: 10 секунд на запрос
  • Коды ошибок: Повторная отправка при временных ошибках сервера (408, 429, 500, 502, 503, 504)
  • Ошибки GPU: Если nvidia-smi недоступен или возвращает некорректные данные, сервер завершит работу с критической ошибкой
  • Критические ошибки: Подробное логирование с завершением работы

Архитектура

┌──────────────────────────────────┐
│        Session Server            │
│                                  │
│  Регистрация (рекурсивно):       │
│  1. Определение IP               │
│  2. Определение hostname         │
│  3. Запрос GPU (nvidia-smi)      │
│  4. POST /servers/register       │
│  5. setTimeout → повтор (30s)    │
│                                  │
│  Обновление GPU (рекурсивно):    │
│  1. Запрос GPU (nvidia-smi)      │
│  2. PATCH /servers/:id/gpu       │
│  3. setTimeout → повтор (1s)     │
└──────────┬───────────────────────┘
           │
           │ HTTP Requests
           │
           ▼
┌──────────────────────────────────┐
│       Main API Server            │
│                                  │
│  1. Проверка по hostname         │
│  2. Создание/обновление          │
│  3. Обновление GPU памяти        │
│  4. Возврат данных               │
└──────────────────────────────────┘

Разработка

Структура проекта

session-server/
├── src/
│   └── index.ts        # Основной файл приложения
├── dist/               # Собранное приложение
├── package.json
├── tsconfig.json
├── bun.build.ts       # Конфигурация сборки
└── README.md

Требования

  • Bun >= 1.0
  • Node.js >= 18 (опционально)
  • TypeScript >= 5.0
  • NVIDIA GPU с установленным nvidia-smi (обязательно)

Лицензия

MIT