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

3.2 KiB
Raw Blame History

Логика доставки почты (Signed Messages v2)

Что отправляет клиент

  • Клиент формирует пару подписанных блоков с одинаковой базой (baseKey):
  • incoming — сообщение для получателя (targetLogin = toLogin).
  • outgoing — копия для отправителя (targetLogin = fromLogin).
  • Пара отправляется методом ReceiveOutcomingMessage (старое имя SendMessagePair оставлено для совместимости).

Что делает сервер при ReceiveOutcomingMessage

  1. Валидирует поля запроса (incomingBlobB64, outgoingBlobB64).
  2. Разбирает оба блока и проверяет, что это корректная пара.
  3. Проверяет пользователей и криптоподписи по каждому блоку.
  4. Пытается сохранить обе записи одной транзакцией:
  • либо добавляются обе записи,
  • либо при дубле/конфликте не добавляется ни одна.
  1. Если пара реально добавилась в БД, сервер запускает realtime-доставку в активные сессии целевых пользователей.
  2. Если это дубль, дальнейшая доставка не выполняется (повтор не разгоняется).

Почему допускаются дубли сети

  • В модели с несколькими серверами возможны повторные пересылки одного и того же сообщения.
  • Дедупликация делается на уровне БД по ключам записи.
  • За счёт этого «шторм» затухает: сервер, который уже видел сообщение, больше его не разгоняет.

Будущая мультисерверная схема (цель)

  • Клиент может отправить ReceiveOutcomingMessage на любой из своих серверов.
  • Сервер-источник:
  • сохраняет пару,
  • рассылает исходящее по серверам пользователя A,
  • рассылает входящее по серверам пользователя B.
  • Остальные серверы повторяют тот же принцип, но благодаря дедупликации повторная пересылка быстро прекращается.

Важные текущие ограничения

  • A) Реальной мультисерверности пока нет. Сейчас фактически предполагается один сервер на пользователя.
  • B) Нет полноценного graceful shutdown для очереди пересылки. Возможен сценарий: запись уже сохранена в БД, но сервер перезагрузился до пересылки дальше. Это нужно доработать отдельно.