45 lines
3.5 KiB
Markdown
45 lines
3.5 KiB
Markdown
# Логика установки звонка через сервер (актуальная)
|
||
|
||
## 1) Ключевые API
|
||
- `CallInviteBroadcast` — широковещательный старт входящего звонка (`type=100`) по пользователю.
|
||
- `CallSignalToSession` — точечный сигнал в конкретную сессию (`RINGING/ACCEPT/DECLINE/TIMEOUT/HANGUP/OFFER/ANSWER/ICE`).
|
||
|
||
## 2) Базовый поток звонка
|
||
1. Инициатор отправляет `CallInviteBroadcast(toLogin, callId, type=100)`.
|
||
2. Сервер отправляет онлайн-сессиям callee событие `IncomingCallInvite` по WS.
|
||
3. Офлайн-сессиям callee сервер отправляет WebPush `incoming_call` (с TTL).
|
||
4. Любая сессия callee, получив invite, может отправить `RINGING`.
|
||
5. Инициатор после первого `RINGING` показывает «Вызываем…».
|
||
6. При `ACCEPT` выбирается одна целевая сессия, остальные получают `HANGUP/stop_call` и закрывают экран входящего.
|
||
7. Далее только выбранная пара сессий обменивается `OFFER/ANSWER/ICE`.
|
||
|
||
## 3) WebPush по звонкам
|
||
### `incoming_call`
|
||
- Используется как fallback для офлайн-сессий.
|
||
- Поля: `kind`, `callId`, `fromLogin`, `fromSessionId`, `toLogin`, `sentAtMs`, `expiresAtMs`.
|
||
- TTL сейчас: **10 секунд**.
|
||
- Если push пришёл после `expiresAtMs`, уведомление не показывается.
|
||
|
||
### `stop_call`
|
||
- Отправляется при завершении/отмене/принятии на другом устройстве.
|
||
- Поля: `kind`, `callId`, `reason`, `fromLogin`, `fromSessionId`, `toLogin`, `sentAtMs`.
|
||
- Service Worker закрывает уведомление по `tag=callId`.
|
||
|
||
## 4) Кнопки в push-уведомлении
|
||
- Для `incoming_call` есть actions:
|
||
- `accept` — «Ответить»
|
||
- `decline` — «Сбросить»
|
||
- По нажатию action:
|
||
- Service Worker шлёт событие в открытые вкладки,
|
||
- и открывает/фокусит UI с параметрами действия.
|
||
- UI пытается выполнить действие сразу (принять/отклонить), если сессия уже авторизована.
|
||
|
||
## 5) Важные ограничения
|
||
- Источник истины по звонку — серверный сигналинг (WS + серверные сигналы), push только вспомогательный канал.
|
||
- Push может прийти с задержкой и не по порядку, поэтому клиент фильтрует устаревшие события (`expiresAtMs` + `callId` + `stop_call`).
|
||
- Полноценный «автоответ в фоне без открытия UI» в web/PWA не гарантируется платформой.
|
||
|
||
## 6) Ограничение текущей архитектуры
|
||
- Сейчас звонки надёжно работают в рамках одного сигнального контура (когда обе стороны подключены к совместимому серверу/кластеру).
|
||
- Межсерверный сценарий «A и B на полностью разных серверах» пока не завершён и вынесен в TODO.
|