TL;DR — многоклиентские сеансы можно проводить полностью без сервера. Два игрока, играющие в крестики-нолики или шахматы, команды, совместно работающие над документом или диаграммой, аудитория, наблюдающая за демонстрацией выступающего, — это лишь примеры того, как несколько экземпляров распределенного приложения должны синхронизироваться. Это можно сделать с помощью автономного приложения, которое не имеет бэкэнда. В этой статье демонстрируется простая настройка в Oracle Cloud Infrastructure — с использованием бессерверной функции (которая на самом деле не является бессерверной, поскольку экземпляр и его переменные остаются активными в течение 5–10 минут после их последнего выполнения) и шлюза API — вместе с автономным HTML-страница, работающая на нескольких распределенных компьютерах. Даже с помощью этой простой настройки мы можем продемонстрировать общее синхронизированное состояние сеанса.
Для получения более подробной информации о дизайне решения, пожалуйста, прочитайте мою предыдущую статью Бессерверная распределенная многопользовательская синхронизация сеансов браузера.
Реализация на OCI
Реализация состоит из:
- Бессерверная функция — обработка POST (создание нового сеанса), PUT (обновление состояния сеанса), GET (получение состояния сеанса)
- Шлюз API — раскрытие функции, обработка запросов, работа с CORS
- Автономное HTML-приложение, которое позволяет инициировать или присоединяться к сеансу, отправлять состояние сеанса, извлекать состояние сеанса.
Бессерверная функция Live-Cache
Функции в OCI создаются с помощью Fn Project с помощью Fn CLI. Конечно, это можно запустить локально, но также и в OCI Cloud Shell — что я и сделал. Функция Fn реализуется с использованием файла конфигурации — func.yaml — и фактической реализации на языке среды выполнения, указанном в файле конфигурации. Node(JS) в данном случае. Файл cache.js реализует функциональность кеша (не намного больше, чем простая карта Map в глобальной переменной, которая сохраняется при индивидуальных запросах).
Примечание: обсуждаемый здесь код доступен на GitHub в этом репозитории.
Функция определена в func.js следующим образом:
Ключевые элементы:
- определить метод HTTP (POST, GET или PUT) и URL-адрес запроса.
- Извлеките параметр sessionKey из URL-адреса запроса.
- В зависимости от метода HTTP вызовите соответствующую функцию в модуле cache.
- Результат вызова модуля кеша возвращается вызывающему функцию.
Модуль Cache не имеет никакой зависимости от функции (Fn) — он может работать где угодно. Кэш глобальных переменных содержит контекст сеанса для каждого многоклиентского сеанса. Новые контексты сеанса создаются из функции startNewSession; ключ для каждого сеанса генерируется и возвращается для повторного использования в последующих вызовах всеми клиентами в сеансе.
Функции writeToCache и readFromCache просты: они помещают значение в кеш для ключа сеанса и извлекают объект контекста сеанса из кеша с помощью ключа сеанса.
Примечание. Отметка времени и версия метаатрибутов, хранящиеся для объектов, хранящихся в кэше, предлагают ступеньку для детального управления версиями, помогая предотвратить конфликты между изменениями от разных клиентов.
Развернутая функция в OCI визуализируется в облачной консоли OCI следующим образом:
Шлюз API — функция раскрытия
Функция должна быть представлена за пределами OCI, чтобы ее можно было использовать в качестве бессерверного многоклиентского посредника, и она должна иметь дело с CORS. Предоставить функцию с помощью шлюза API OCI довольно просто:
- создать шлюз API
- создать развертывание API
- настроить маршрут:
Разверните шлюз API. Затем: получите (общедоступную) конечную точку — и начните вызывать.
Автономное HTML-приложение — использование многоклиентского кэша сеансов
Автономное HTML-приложение, которое я использую здесь, чтобы продемонстрировать возможность взаимодействия автономных клиентов (общий сеанс), простое и некрасивое.
Одно и то же приложение работает на нескольких компьютерах одновременно — возможно, в разных местах. Из каждого местоположения приложение взаимодействует с функцией, представленной на шлюзе API, как описано выше.
Код HTML довольно прост — как и следовало ожидать:
Код JavaScript, который вдохнул жизнь в этот HTML:
Функция startSession() вызывает операцию POST для серверной функции; retrieveSessionContext() вызывается с интервалом, который срабатывает каждые 5 секунд — он вызывает операцию GET для бэкэнд-функции, а pushSessionContext() вызывается каждый раз, когда пользователь отправляет сообщение; эта функция вызывает операцию PUT для API и серверной функции.
Детали кода для этих функций:
Вывод
С помощью двух облачных ресурсов — API-шлюза и бессерверной функции — которые требуют минимальных затрат (1 млн вызовов API-шлюза за 3 доллара в месяц и 2 млн бесплатных вызовов функций в месяц), нам удалось создать контекст сеанса с несколькими клиентами, который легко распределяется между несколькими удаленно распределенными клиентами. Это позволяет автономным веб-приложениям поддерживать расширенное поведение, такое как совместная работа в команде и возможности, подобные широковещательным.
Я продемонстрировал реализацию в Oracle Cloud Infrastructure. Конечно, подобную реализацию можно легко создать в Azure, AWS или других общедоступных облаках.
Ресурсы
Моя более ранняя статья, посвященная идее безсерверной синхронизации клиентов: https://technology.amis.nl/frontend/serverless-distributed-multi-user-browser-session-synchronization/
Источники этой статьи на GitHub: https://github.com/lucasjellema/live-cache
Сценарий Katacoda, представляющий функции в OCI: https://www.katacoda.com/redexpertalliance/courses/oci-course/functions-on-oci
Сценарий Katacoda по внедрению API Gateway в OCI: https://www.katacoda.com/redexpertalliance/courses/oci-course/api-gateway-on-oci
Первоначально опубликовано на https://technology.amis.nl 25 мая 2021 г.