» » » Веб-мессенджеры и эвент 'beforeunload': как сохранить миллион сообщений при закрытии страницы

 

Веб-мессенджеры и эвент 'beforeunload': как сохранить миллион сообщений при закрытии страницы

Автор: admin от 9-01-2018, 15:35, посмотрело: 40

Веб-мессенджеры и эвент 'beforeunload': как сохранить миллион сообщений при закрытии страницы

В конце лета мы добавили в наше облако Voximplant поддержку месседжинга. Теперь с помощью него и россыпи SDK под разные платформы можно делать собственные мобильные или веб-мессенджеры: голосовые звонки в любых комбинациях между телефонными сетями и SDK — есть, видеозвонки между SDK — есть, месседжинг — есть. А еще у текстовых сообщений есть ключевое отличие от голосовых и видеозвонков: их контент должен оставаться. Voximplant может записать голосовой и видеозвонок на стороне облака и отдать URL с получившимся файлом, но это «медленная» история для CRM, систем управления заказами и колл-центров. А сообщения — это быстрая история. Пользователь очень огорчается, когда клик по «старому» чату в Skype вызывает зависание мобильного или веб-приложения, которое пытается выкачать хоть сколько-нибудь истории с нагруженных серверов по неустойчивому 3G. В наших SDK мы предусмотрели несколько механизмов для максимально быстрой работы с историей сообщений, о которых под катом.

Messenger, который дает доступ к API и позволяет получать эвенты. Общение между пользователями начинается, когда один из них создает объект Conversation («беседа» или «чат» на двоих и более) и они начинают обмениваться сообщениями с помощью метода этого объекта sendMessage. О происходящих событиях клиенты узнают с помощью эвентов. Например, если пользователь «А» хочет отправить пользователю «Б» сообщение в первый раз, то он создает conversation на двоих, после чего им обоим приходит эвент CreateConversation, по которому пользователь «Б» узнает, что с ним хотят общаться. Также эвенты сигнализируют о новых сообщениях, присоединяющихся к conversations и покидающим их пользователям, смене админского статуса или о том, что пользователь печатает текст.



Вся эта идиллия длится ровно до того момента, пока один из пользователей не закрывает вкладку с чатом. И не открывает ее снова через день. Или через месяц. Или через год. Что нужно сделать разработчику, чтобы пользователь увидел все то новое, что произошло за время его отсутствия? И желательно так, чтобы не подвесить браузер.



Сериализация и нумерация — два кита истории сообщений



Главная деталь механизма — это последовательная нумерация всех сообщений в conversation. В эвенте SendMessage есть поле seq, которое содержит уникальный идентификатор сообщения. Идентификатор уникален в рамках conversation и постоянно увеличивается. Соответственно, если мы закрыли страницу браузера, открыли ее через год и хотим узнать, какие новые сообщения за это время пришли, все что нужно сделать – это хранить где-нибудь sequence id последнего полученного сообщения, а после открытия страницы запросить у облака недостающие сообщения. Или, например, последние несколько десятков, и подгружать остальные, только если пользователь решил посмотреть лог.

Веб-мессенджеры и эвент 'beforeunload': как сохранить миллион сообщений при закрытии страницы

Вспомогательная деталь — это сериализация. SDK высокоуровневый и работает с объектами. Например, если мы хотим получить новые сообщения для conversation, то вначале нужно получить объект для этого conversation с помощью getConversation, а затем — сообщения с помощью метода этого объекта, retransmitEvents



Но если мы только загрузили страницу, то откуда у нас объекты? У нас кучка id'шек, предусмотрительно сохраненных в localStorage. А объекты придется создавать, и каждое такое создание объекта — это запрос к облаку для получения нужной информации.



Решение — встроенный механизм сериализации объектов с помощью методов toCache и create...FromCache, которые создают JSON-представление внутренностей объекта и могут восстановить объект из такого JSON без обращения к серверу. А JSON можно хранить в localStorage, мгновенно восстанавливая при загрузке страницы сотню каналов и миллион сообщений.



Миллион сообщений — а javascript или localStorage не лопнут?



С веб-страницами, в отличии от desktop и мобильных приложений, все сложно. Когда пользователь командует «закрыть вкладку» или «закрыть браузер», срабатывает эвент «beforeunload», на который можно подписаться. Сообщения «у вас есть несохраненные данные» в google docs — это строка, которую разработчик вернул из обработчика. Раньше в нем можно было делать даже alert'ы, но скам-страницы «ваш браузер заблокирован, дайте денег» мягко намекнули разработчикам браузеров, что многое позволять в обработчике «beforeunload» не стоит.



Тем не менее, современные браузеры дают нашему коду несколько секунд, прежде чем покажут такое сообщение и пользователь начнет беспокоиться:



Веб-мессенджеры и эвент 'beforeunload': как сохранить миллион сообщений при закрытии страницы

А за несколько секунд вполне можно сериализовать в localstorage несколько сотен conversations с миллионом сообщений. Но тут важно помнить, что по умолчанию localStorage ограничен 5-10 мегабайтами, и даже меньше для мобильных браузеров или если пользователь копался в настройках.



Лучшие практики, чтобы ничего не лопнуло



Если вы делаете новый «Skype for Web» и планируете действительно большое количество сообщений у ваших пользователей, то для хранения сериализованных объектов лучше использовать indexedDB, которое сейчас поддерживают все популярные браузеры. Квоты там по умолчанию намного больше и можно явно попросить у пользователя еще с помощью «Quota Management API» и специфичных браузерных штук.



Второй момент — если в каком-то conversation с последнего посещения накопилось много сообщений, то будет разумно запросить у сервера последние несколько десятков, а остальные подгрузить, только если пользователь поскроллил лог. Получается разновидность «обратного бесконечного скролла» — новые элементы будут возникать не снизу, как при скролле страницы фейсбука, а сверху.



В этом году мы планируем существенно расширить наш messaging, добавив управление через HTTP и вебхуки. Это позволит разработчикам делать интеграцию с другими мессенджерами, программное управление сообщениями вроде «чата с операторами» и другие интересные штуки.


Источник: Хабрахабр

Категория: Операционные системы » Linux

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *