SHiNE-server/Логика_доставки_почты.md

35 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Логика доставки почты (Signed Messages v2)
## Что отправляет клиент
- Клиент формирует **пару подписанных блоков** с одинаковой базой (`baseKey`):
- `incoming` — сообщение для получателя (`targetLogin = toLogin`).
- `outgoing` — копия для отправителя (`targetLogin = fromLogin`).
- Пара отправляется методом `ReceiveOutcomingMessage` (старое имя `SendMessagePair` оставлено для совместимости).
## Что делает сервер при `ReceiveOutcomingMessage`
1. Валидирует поля запроса (`incomingBlobB64`, `outgoingBlobB64`).
2. Разбирает оба блока и проверяет, что это корректная пара.
3. Проверяет пользователей и криптоподписи по каждому блоку.
4. Пытается сохранить обе записи **одной транзакцией**:
- либо добавляются **обе** записи,
- либо при дубле/конфликте не добавляется **ни одна**.
5. Если пара реально добавилась в БД, сервер запускает realtime-доставку в активные сессии целевых пользователей.
6. Если это дубль, дальнейшая доставка не выполняется (повтор не разгоняется).
## Почему допускаются дубли сети
- В модели с несколькими серверами возможны повторные пересылки одного и того же сообщения.
- Дедупликация делается на уровне БД по ключам записи.
- За счёт этого «шторм» затухает: сервер, который уже видел сообщение, больше его не разгоняет.
## Будущая мультисерверная схема (цель)
- Клиент может отправить `ReceiveOutcomingMessage` на любой из своих серверов.
- Сервер-источник:
- сохраняет пару,
- рассылает исходящее по серверам пользователя A,
- рассылает входящее по серверам пользователя B.
- Остальные серверы повторяют тот же принцип, но благодаря дедупликации повторная пересылка быстро прекращается.
## Важные текущие ограничения
- **A) Реальной мультисерверности пока нет.** Сейчас фактически предполагается один сервер на пользователя.
- **B) Нет полноценного graceful shutdown для очереди пересылки.** Возможен сценарий: запись уже сохранена в БД, но сервер перезагрузился до пересылки дальше. Это нужно доработать отдельно.