3.5 KiB
3.5 KiB
Логика установки звонка через сервер (актуальная)
1) Ключевые API
CallInviteBroadcast— широковещательный старт входящего звонка (type=100) по пользователю.CallSignalToSession— точечный сигнал в конкретную сессию (RINGING/ACCEPT/DECLINE/TIMEOUT/HANGUP/OFFER/ANSWER/ICE).
2) Базовый поток звонка
- Инициатор отправляет
CallInviteBroadcast(toLogin, callId, type=100). - Сервер отправляет онлайн-сессиям callee событие
IncomingCallInviteпо WS. - Офлайн-сессиям callee сервер отправляет WebPush
incoming_call(с TTL). - Любая сессия callee, получив invite, может отправить
RINGING. - Инициатор после первого
RINGINGпоказывает «Вызываем…». - При
ACCEPTвыбирается одна целевая сессия, остальные получаютHANGUP/stop_callи закрывают экран входящего. - Далее только выбранная пара сессий обменивается
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.