Данный набор скриптов предназначен для серверной поддержки системы доставки сообщений клиентам о происходящих событиях. В качестве транспорта возможно использовать механизмы long polling или websocket.
Сервер, поддерживающий данные протоколы не входит в данный репозитарий. Здесь только часть связанная с хранением/доставкой данных.
Несмотря на то, что тарантул поддерживает асинхронную мастер-мастер, однако делать push можно только в один инстанс. Subscribe можно делать на любом инстансе. Таким образом при увеличении нагрузки нужно просто добавлять инстансы-реплики которые будут обслуживать клиентов, которые принимают сообщения, а все генерируемые сообщения отправлять на выделенный инстанс.
Для работы с данным лонгпулингом требуется
- драйвер к тарантулу, поддерживающий асинхронный доступ (множество запросов по одному коннекту). Например DR::Tnt
- асинхронный вебсервер. Например Twiggy или Coro::Twiggy
- Tarantool версии 1.6 и больше
- данный набор lua
lp = require 'lp'
lp:init{ ... }
lp:push(key, value)
lp:push_list(key1, value1, key2, value2, ...)
...
local events = lp:subscribe(12345, 25, key1, key2, ...)
Для установки необходимы файлы из директории lua/
lp = require 'lp'
lp:init{ option = value }
Опции инициализации:
expire_timeout = 1800
- Максимальное время жизни события в БДserialize_key_method = 'none'
- Способ сериализации ключаlsn_check_interval = 1
- Интервал проверки на наличие новых событий (данная опция актуальна только для реплик)run_expired = true
- Запускать или нет на данном инстансе процесс удаления устаревших записей
Каждое сообщение хранится в виде тапла:
id
- идентификатор сообщения (присваиваетсяpush
)created
- время когда создано сообщение (используется процессом expiration)key
- ключ сообщенияdata
- данные связанные с сообщением (в обычном случае - сериализованный (например JSON) объект).
Поскольку ключ сообщения требуется индексировать, то использование составных ключей возможно только при условии включения механизма сериализации ключа.
Доступные механизмы сериализации:
none
(по умолчанию) - не сериализовать ключmsgpack
- сериализовать при помощи msgpackjson
- сериализовать при помощи jsoncolon
- сериализовать в строку при помощи конкатенации через двоеточие
Есть два метода, позволяющие добавить одно или несколько сообщений:
lp:push(key, value)
lp:push_list(key1, value1, key2, value2, ...)
Второй метод просто перевызывает первый в цикле.
local list = lp:subscribe(id, timeout, key1, key2, ...)
Подписывается на получение сообщений с ключами key1
, key2
, итп.
Подписка осуществляется на интервал времени timeout
.
В качестве id
необходимо передать стартовый id
с которого
необходимо получать сообщения. id=0
означает: "ожидать все сообщения,
начиная от текущего времени".
В списке возвращаются все полученные сообщения по переданным ключам
(если они есть), а так же завершающая запись, содержащая в себе
id
, который можно использовать для следующего subscribe
.
Таким образом алгоритм работы клиента выглядит следующим образом.
- начало:
id=0
- запрос
lp:subscribe(id, timeout, key1, key2, ...)
- обработка списка полученных сообщений (все элементы полученного списка кроме последнего)
- id=id из последнего элемента списка
- перейти к шагу 2
Для случая "лонгпулинг на сайте" пункты 1, 3, 4, 5 делаются на клиенте при помощи JavaScript. Пункт 2 делается на сервере при помощи асинхронного вебсервера (например Twiggy или Node.JS).