События сервера для мобильных web-приложений

Некоторое время назад возникла потребность реализовать в своём мобильном web-приложении оповещение клиента (фронт) о событиях, происходящих на сервере (бэк). Я рассматривал технологию Server Sent Events, как более простую альтернативу Websockets ("HTTP & text" vs. "TCP & binary").

Особенностями мобильных приложений (в том числе и мобильных web-приложений) является то, что они, зачастую, работают в условиях постоянного переподключения к интернету (например, переключение с мобильного подключения на wifi-подключение или переключение устройства между различными wifi-точками). В таких условиях долгоживущим соединениям существовать сложно (а SSE и Websockets — это долгоживущие соединения).

Анализируя ситуацию, обнаружил такие вещи:

  • Сервер не всегда может определить, что клиент отвалился. В некоторых ситуациях сервер продолжает отправлять сообщения и сообщения безвозвратно пропадают в Сети.
  • Без помощи со стороны web-приложения у сервера нет возможности определить, это один браузер с одного мобильного устройства открыл два отдельных SSE-соединения или это два разных браузера с разных мобильных устройств открывают соединения из-за одной точки доступа.

У меня получились такие выводы:

  • Мобильное приложение при установлении SSE-соединений с сервером должно генерировать некий UUID, чтобы с его помощью сервер мог отличить, когда web-приложение подключается повторно после разрыва соединения, а когда подключаются разные web-приложения с одинаковыми внешними IP-адресами.
  • SSE лучше не использовать для доставки клиенту бизнес-данных (например, данных о товаре, добавленном в каталог), но использовать для доставки оповещения о том, что нужно запросить бизнес-данные (что в каталоге появился новый товар и что клиент может запросить данные о всех новых товарах). В этом случае, если какой-то сигнал не дойдёт то клиента, то пропущенный товар попадёт к клиенту при обработке следующего сигнала. Т.е., бизнес-логика строится из расчёта, что по SSE сервер отправляет (push) сигналы клиенту, а клиент запрашивает (pull) данные, связанные с сигналами, отдельными запросами.
  • IMHO, желательно, чтобы клиент отдельным HTTP-запросом отправлял на сервер подтверждение каждому полученному от него сообщению. В таком случае сервер получает шанс закрыть соединение, если клиент ушёл в offline (если подтверждение о получении сообщения не пришло в течение определённого timeout’а).

Более подробно — здесь.

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

1
4 комментария