Предположим, что это автономное приложение на основе браузера (или настольного электрона), работающее только на стороне клиента. Несколько пользователей работают с этим приложением одновременно, на своих ноутбуках и в (возможно, очень) разных местах, возможно, по всему миру. Можно предположить, что они работают над общим объектом. Документ, диаграмма, игровая доска, технологический радар, белая доска и т. д. Если это так, было бы полезно, если не необходимо, синхронизировать содержимое в средах браузера.

С обычными веб-приложениями, поддерживаемыми стеком на стороне выделенного сервера, это достигается довольно легко. WebSockets или SSE могут транслировать изменения всем клиентам, а запросы AJAX используются для отправки обновлений от каждого клиента на мощный сервер. Google Docs, Office365, MS Teams и Miro — лишь некоторые из примеров.

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

В этой статье я расскажу о том, что началось как мысленный эксперимент и превратилось в рабочий прототип очень легкого подхода к синхронизации контекста приложения между пользователями, распределенными даже по всему миру. Этот подход использует не что иное, как бессерверные функции — дешевые (бесплатные для небольших сред), легкие и чрезвычайно простые в настройке.

Простейший подход только с двумя клиентами можно представить следующим образом:

Пользователь А запускает приложение локально. Из их локального браузера отправляется простой HTTP-запрос (1), который обрабатывается шлюзом API и передает его бессерверной функции. Функция генерирует новый ключ сеанса и возвращает этот ключ в ответе 2). Этот ключ связывает пользователей и общий контекст или состояние сеанса.

Пользователь должен поделиться ключом сеанса (шаг 3) с другими пользователями, которые хотят и могут присоединиться к сеансу. Каждый пользователь должен предоставить этот ключ приложению. Используя ключ сеанса, пользовательский экземпляр локального приложения может установить фактический контекст приложения (4). Это состояние принимается бессерверной функцией и хранится в кэше, определяемом сеансовым ключом. Примечание: находится ли этот кеш в памяти, в базе данных или в файловом хранилище, не имеет значения и данный момент; этот выбор реализации может быть сделан и пересмотрен в любой момент, в основном в зависимости от нефункциональных требований, таких как размер контекста сеанса, количество участников сеанса, частота обновления и особенно требуемая надежность и продолжительность сеанса.

Экземпляр приложения второго пользователя теперь присоединяется к сеансу (5) с использованием ключа сеанса и запрашивает текущее состояние. С этого момента оба экземпляра приложения могут публиковать обновленный контекст сеанса [в бессерверную функцию] и опрашивать последнее состояние контекста сеанса (например, шаг 6).

Более продвинутая реализация, возможно, будет включать некоторую форму обнаружения изменений, контроль версий и детальную обработку конфликтов изменений, чтобы не допустить непреднамеренного переопределения изменений контекста сеанса. И обеспечение безопасности, чтобы гарантировать, что никто не сможет угадать ключ сеанса и присоединиться к сеансу. Однако давайте сначала сосредоточимся на базовой реализации.

Совместное использование состояния через облака

Какие основные элементы:

  1. Бессерверная функция для обработки
  • POST запрос нового сеанса, возврат нового ключа сеанса
  • Состояние PUT для сеанса
  • ПОЛУЧИТЬ состояние для сеанса

2. Шлюз API для предоставления бессерверной функции и маршрутизации к ней HTTP-запросов.

3. статическое HTML-приложение, которое

  • отправить HTTP-запрос для новой сессии [ключ]
  • позволяет пользователю ввести сеансовый ключ
  • периодически опрашивает текущее состояние сеанса (и обрабатывает это состояние)
  • отправляет контекст сеанса после того, как были сделаны локальные обновления состояния

Первоначальная реализация функции может быть создана локально, и как только она зарекомендует себя как посредник между несколькими локальными сеансами, мы можем развернуть ее на стороне облака, предоставить через шлюз API и опробовать в облаке. Первоначальная реализация будет полагаться на глобальный контекст (память) для функции и не будет использовать автономный кеш, базу данных или хранилище файлов.

Быстрая демонстрация

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

1. Клиент 1 Начать многоклиентский сеанс

2. Клиент 1 — установлен многоклиентский сеанс.

3. Клиент 2 — присоединиться к многоклиентскому сеансу, введя ключ сеанса.

4. Клиент 2 — присоединился к сеансу

5. Клиент 1 — введите сообщение, которое добавляется в контекст мультиклиентской сессии.

6. Клиент 1 — сообщение было добавлено в контекст сеанса, и контекст был помещен в бессерверный многоклиентский кэш сеанса.

7. Клиент 2 — получил обновленный контекст сессии (мой стартовый ход) и добавил в контекст сессии

8. Клиент 1 — получил обновления контекста сеанса, сделанные клиентом 2.

Вывод

Эти визуальные эффекты могут вас не впечатлить. Однако они рассказывают довольно мощную историю. Два экземпляра приложения, работающие независимо друг от друга, на разных аппаратных средствах, возможно, даже на разных континентах, информируют друг друга, позволяя своим пользователям сотрудничать в режиме реального времени. И эти экземпляры приложений не поддерживают механизм с отслеживанием состояния. Эти два приложения – это клиентские браузерные приложения, которые используют исходящие HTTP-запросы для синхронизации состояния приложения.

Чтобы увидеть реальную реализацию, ознакомьтесь с этой статьей, которая проведет вас через реальную, хотя и простую реализацию — в Oracle Cloud Infrastructure.

Ресурсы

Моя статья, демонстрирующая реальный рабочий пример синхронизации состояния сеанса между автономными веб-приложениями на Medium: https://lucasjellema.medium.com/implementing-serverless-multi-client-session-synchronization-with-oracle-cloud-infrastructure -cf6a9fff7a02»

Моя статья посвящена созданию самостоятельного кэш-решения с бессерверными функциями OCI: https://medium.com/oracledevs/somewhat-stateful-serverless-functions-on-oracle-cloud-infrastructure-implementing-a-diy-cache-433af41ce28d

Первоначально опубликовано на https://technology.amis.nl 25 мая 2021 г.