Перейти к содержанию

Кросс-клиентная синхронизация

Проблема

Один человек может открыть веб и Telegram одновременно. Несколько людей играют с разных каналов. Состояние должно быть единым и согласованным.

Модель Participant

  • Один Participant на человека в сессии
  • Два presence-канала: presence_web, presence_telegram
  • Один голос в игре — не два хода

Control channel

Правило Описание
Default Последний канал, с которого пришло действие, становится control_channel
Mirror Второй канал показывает state read-only до следующего действия с него
Active turn Только current_player may submit actions

Поток события

sequenceDiagram
    participant TG as Telegram
    participant Bot as telegram-bot
    participant Game as game-runtime
    participant Redis as Redis PubSub
    participant RT as realtime-service
    participant Web as web-app

    TG->>Bot: callback choose_cell
    Bot->>Game: POST /games/{id}/actions
    Game->>Game: validate, apply, audit
    Game->>Redis: publish game.state_changed
    Redis->>RT: event
    RT->>Web: WebSocket push
    Redis->>Bot: event
    Bot->>Bot: fetch media URL, edit_message

Идемпотентность

POST /api/v1/games/{game_id}/actions
{
  "action_id": "550e8400-e29b-41d4-a716-446655440000",
  "action_type": "choose_cell",
  "payload": { "row": 3, "col": 5 }
}
  • Повтор с тем же action_id200 с тем же результатом, без дубля
  • Конфликт фазы → 409 CONFLICT

Optimistic UI (веб)

  1. Клиент подсвечивает клетку локально
  2. Отправляет action
  3. При ошибке — rollback из последнего WS state
  4. При успехе — подтверждение от WS (authoritative)

Telegram рендер

Шаг Действие
1 game.state_changed → bot handler
2 GET /media/render?game_id=... → PNG URL
3 edit_message_media с фото + inline keyboard
Fallback Текстовая сетка ASCII + кнопки если media fail

Reconnect (веб)

  1. WS disconnect → exponential backoff reconnect
  2. On connect: GET /games/{id}/state + subscribe WS topic
  3. Merge с локальным буфером pending actions

Latency budget

Этап Target
API apply < 300 ms p95
Pub/Sub → WS < 200 ms
Bot edit_message < 500 ms
End-to-end < 1 s p95

Связанные FR/NFR

FR-003, FR-025–FR-029, NFR-002