Курс «Архитектура мессенджера» · Часть 2 · Соединение и доставка

Раздел 5. Офлайн-доставка и пуши

Очередь недоставленных сообщений; что происходит при переподключении; push-уведомления (APNs/FCM) и зачем они нужны поверх собственного соединения.

В прошлом разделе мы закончили на важной мысли: онлайн и офлайн — это одна развилка, которая случается уже после того, как сообщение сохранено. Теперь разберём вторую ветку: что делать, когда получателя нет в сети. В тренажёре нажми «▶ Офлайн» — текст ниже объясняет логику этих шагов.

Проблема: толкать некуда

Когда оба в сети, сервер просто проталкивает сообщение по живой связи получателя. Но если получатель не в сети — живой связи нет, и протолкнуть некуда. При этом сообщение уже сохранено на сервере (это произошло до развилки), так что терять его нельзя ни в коем случае. Значит, нужно где-то его придержать до возвращения получателя.

Очередь ожидания

Решение — очередь ожидания: можно думать о ней как о личном почтовом ящике каждого пользователя. Пока Боб не в сети, все адресованные ему сообщения складываются в его очередь и спокойно там ждут.

Что важно понимать про очередь:

  • это надёжное хранилище, а не «временный буфер в памяти»: даже если сервер перезапустят, очередь переживёт это;
  • она хранит порядок — чтобы при возвращении Боб увидел сообщения в той же последовательности, в какой их отправили;
  • сообщение лежит в очереди, пока получатель не подтвердит, что забрал его. Только после подтверждения его можно убрать.

Что происходит при возвращении

Боб открыл приложение и снова вышел в сеть. Дальше:

  1. Его устройство переподключается — заново устанавливает живую связь через балансировщик и сервер соединений (как в Разделе 3).
  2. Сервер соединений отдаёт всё накопленное из очереди Боба.
  3. Устройство Боба подтверждает, что получило сообщения (теми самыми квитанциями из Раздела 4).
  4. Сервер по подтверждениям очищает очередь — забранные сообщения больше не нужно держать.

Чтобы не слать одно и то же дважды, клиент при возвращении как бы говорит «я всё получил вот до этого момента», и сервер отдаёт только то, что новее. Это опирается на уникальные номера сообщений (Раздел 6).

Зачем нужны пуши, если есть своя связь

Самый частый вопрос по этому разделу — и контринтуитивный. Казалось бы: у нас есть постоянная связь, зачем какие-то сторонние уведомления?

Дело в том, что своя связь жива только пока приложение открыто. Как только пользователь свернул или закрыл приложение, операционная система телефона разрывает эту связь — она не разрешает приложениям бесконечно держать соединение в фоне, потому что это сажало бы батарею. И тогда сервер физически не может достучаться до закрытого приложения сам.

Разбудить устройство имеет право только системная служба уведомлений — у неё особая привилегия от операционной системы:

  • APNs (Apple Push Notification service) — служба уведомлений Apple, для iPhone и iPad;
  • FCM (Firebase Cloud Messaging) — служба уведомлений Google, для Android.

Как это работает: сервер не достучался до Боба напрямую → он отправляет запрос в APNs или FCM → те доставляют уведомление на телефон → Боб видит «новое сообщение», открывает приложение → оно переподключается → забирает сообщения из очереди. То есть пуш не доставляет само сообщение — он только будит устройство, чтобы приложение пришло за сообщением само.

Тонкости, которые ценят на интервью

Уведомление — это не сообщение. Часто в пуш кладут лишь «у вас новое сообщение» (а иногда и вовсе пустышку), а сам текст подтягивается уже после открытия приложения. При сквозном шифровании иначе и нельзя: сервер не знает текста сообщения, поэтому положить его в уведомление не может в принципе (подробнее — Раздел 19).

Пуш — это «лучшая попытка», без гарантии. Телефон может быть выключен, без сети, уведомления отключены. Поэтому источником правды остаётся очередь на сервере, а пуш — лишь способ поторопить. Нельзя считать, что «отправили пуш = доставили». Доставка фиксируется только подтверждением от устройства, как в онлайн-сценарии.

Вопросы интервьюера (с разбором)

«Куда девается сообщение, если получатель офлайн?» Образец: «Оно к этому моменту уже сохранено на сервере, поэтому не теряется. Раз доставить сразу нельзя — оно кладётся в очередь ожидания получателя, его личный надёжный ящик, и хранится там с сохранением порядка, пока получатель не вернётся и не заберёт его.»

«Как он получит сообщения при возвращении?» Образец: «Устройство переподключается, заново поднимает живую связь, сервер отдаёт всё накопленное из очереди по порядку. Устройство подтверждает получение квитанциями, и сервер по этим подтверждениям очищает очередь. Чтобы не дублировать, клиент сообщает, до какого момента он уже всё получил.»

«Зачем нужны APNs/FCM, если у нас есть своё соединение?» Образец: «Своё соединение живёт, только пока приложение открыто. В фоне операционная система его разрывает ради экономии батареи, и достучаться до закрытого приложения мы сами не можем. Разбудить устройство имеет право лишь системная служба уведомлений — APNs у Apple, FCM у Google. Она не доставляет само сообщение, а лишь будит приложение, чтобы оно переподключилось и забрало сообщение из очереди.»


#мессенджер #офлайн-доставка #очередь-сообщений #пуш-уведомления #apns-fcm #подготовка-к-интервью