⚫От клиентов к серверу
⚫Идемпотентны
⚫Обычная фьюча которая ждет результата
⚫От клиентов к серверу
⚫Что-то меняют на сервере
⚫Обычно не имеют возвращаемого результата
⚫Ходят внутри сервера или от сервера к клиенту
⚫Источник событий с сервера
⚫На каждый источник свой канал
⚫Сервер постит события в канал
⚫Все клиенты, которые слушают канал, получают эти события
⚫Хранит данные
⚫Заполняется запросом к серверу
⚫Подписывается на каналы
⚫Вьюхи отображают данные из моделей
⚫Модели персистентны
⚫Когда что-то меняем на клиенте - отправляем команду на сервер
⚫Доставка команд должна быть гарантированной
Клиент
Сервер
Клиент
Сервер
Клиент
Сервер
Id: 15
Id: 15
⚫Без порядка отправки будет рассинхронизация
⚫Команды отправляются строго по одной из очереди
⚫Пока не принято подтверждение команды - следующая не отправляется
⚫Команды сохраняются в очередь на клиенте
Клиент
Сервер
Command
Event
Нужно устанавливать связь между событием и командой, которая это событие сгенерировала
Событие можно использовать и как подтверждение команды
1. Все-таки делать подтверждение
2. Иметь специальный канал типа "Сущности, созданные мной"
⚫Без порядка будет рассинхронизация
⚫Нужно хранилище необработанных событий.
⚫Если событие пропущено, то последующие ждут, пока не примется предыдущее
Клиент
Сервер
⚫Сплошная нумерация событий внутри канала
⚫Пока не понятно, что лучше
⚫Передавать айди предыдущего в следующем событии
⚫Инвалидация всей модели и запрос нового снапшота?
⚫Использовать оба варианта?
⚫Запросить недоставленные события и обработь их в правильном порядке?
1. Tолько клиент
2. Только сервер
⚫Плохо масштабируется
⚫Не зароутить сообщения на клиенте
3. И клиент и сервер
⚫Наш вариант!
Проблема - как понять, что мы действительно приняли все события в канале?
Вдруг сервер нам что-то отправляет, а до нас это не доходит?
⚫Клиент периодически опрашивает сервер
⚫Актуальность проверяем по последнему принятому событию в канале
⚫Если события были - запросить недоставленные
⚫Проблема - после длительного использования приложения может быть очень много каналов на клиенте
⚫Опрашивать не через константные промежутки времени, а в зависимости от того, насколько канал “горяч”
⚫У каждого юзера есть свой актор
⚫Актор продолжает работу и когда клиент оффлайн
⚫Через него проходит доставка событий на клиент
⚫При выходе онлайн актор синхронизирует состояние клиента и сервера
⚫Минус - добавит состояния на сервер
Например, мы были оффлайн сутки, и написали в чат 100 сообщений
В это же время в том же чате написали 300 сообщений
Что делать?
Команды - просто отдаем на сервер
Актуализируем каналы на клиенте
Как быть с большим расхождением модели на клиенте и сервере?
⚫Инвалидация всей модели и запрос нового снапшота?
⚫Пытаться кусками подтягивать снапшоты?
⚫Всегда подтягивать события?
1. Если событий мало - сервер отправляет новые
⚫Модель либо инвалидируется
2. Если событий много
⚫Либо подтягивается новый снапшот
⚫Конкретное поведение зависит от модели
Что делать с большим количеством пропущенных событий, когда мы решаем, что проще перекачать снапшот?
1. Забиваем
⚫Как определить степень старости?
2. Забиваем только на старые
⚫Не старые надо перекачать
3. Показать сообщение юзеру - "У вас там-то много событий"
1. У каждого юзера может быть несколько клиентов
2. Нужно будет везде продумывать batch processing
3. Возможно часть проблем не актуальна из-за гарантий Web-socket
4. В оффлайне будем использовать пуш уведомления
1. Очень много проблемных мест
2. Стараться больше опираться на снапшоты и запросы
3. ИМХО - в альфе лучше сделать только онлайн и считать, что у нас всегда все гарантированно доставляется.