Модуль Pull в 1С-Битрикс - события в браузере в реальном времени
Модуль Pull заменяет периодический опрос сервера на доставку событий по инициативе сервера: счётчик обновляется сам, уведомление появляется мгновенно, открытые вкладки синхронизируются. Разберём прикладную сторону - как отправить команду и как её принять.
Как это работает
Два режима работы. Рекомендуемый - постоянное подключение к серверу очередей: браузер держит долгоживущее соединение с отдельным push-сервером, что требует настройки инфраструктуры. Без неё модуль работает в режиме опроса: клиент обращается к серверу раз в минуту, при наличии данных интервал сокращается до десяти секунд, а затем при пустых ответах снова растёт.
Технологии доставки: длинные опросы как основной механизм, веб-сокеты как современная альтернатива и специальный модуль веб-сервера для серверного решения.
Отправка - это команда в очередь получателю. Есть отправка конкретному пользователю или гостю, рассылка подписанным на тег и отдельная сущность push-уведомлений на устройства. В новом коде серверная отправка выполняется через D7-класс события.
Структура команды - три поля: идентификатор модуля-отправителя, имя команды и объект произвольных параметров. Ровно эта тройка приходит на клиент.
Клиентская сторона подключает библиотеку и подписывается на команды. Подписка фильтрует по модулю и команде, поэтому чужие события обработчику не мешают.
Инфраструктурная настройка push-сервера - ключ подписи, порты, служба на Node.js - описана в статье про окружение.
Примеры
1. Отправка команды пользователю
\Bitrix\Main\Loader::requireModule('pull');
\Bitrix\Pull\Event::add($userId, [ 'module_id' => 'mymodule', 'command' => 'orderStatusChanged', 'params' => [ 'orderId' => $orderId, 'status' => $status, ],]);Идентификатор модуля и имя команды на клиенте используются для фильтрации - берите осмысленные и уникальные значения.
2. Рассылка подписанным
// подписать пользователя на тег\CPullWatch::Add($userId, 'ORDER_' . $orderId);
// отправить всем подписанным на тег\CPullWatch::AddToStack('ORDER_' . $orderId, [ 'module_id' => 'mymodule', 'command' => 'orderUpdated', 'params' => ['orderId' => $orderId],]);Модель подписки на тег удобна, когда получателей заранее не знаешь: подписались все, кто открыл страницу заказа, и они же получат обновление.
3. Приём на клиенте
BX.PULL.subscribe({ moduleId: 'mymodule', callback: (data) => { if (data.command === 'orderStatusChanged') { updateStatus(data.params.orderId, data.params.status); } },});// подписка на конкретную командуBX.PULL.subscribe({ type: BX.PullClient.SubscriptionType.Server, moduleId: 'mymodule', command: 'orderUpdated', callback: (params) => refresh(params.orderId),});Подписку вешают после подключения клиентской библиотеки. Если событий много, фильтруйте их по команде, а не разбирайте все подряд в одном обработчике.
Справочник API
| API | Назначение | Особенности |
|---|---|---|
Bitrix\Pull\Event::add() | отправка события в D7-стиле | актуальный способ |
CPullStack | отправка конкретному пользователю или гостю | легаси-класс |
CPullWatch::Add() | подписка пользователя на тег | |
CPullWatch::AddToStack() | рассылка подписанным на тег | получатели заранее неизвестны |
CPushManager | push-уведомления на устройства | отдельная от команд сущность |
CPullOptions | проверка состояния модуля | |
| структура команды | модуль, команда, параметры | эта же тройка приходит на клиент |
pull.client | клиентская библиотека | подключается в публичной части |
BX.PULL.subscribe() | подписка на команды | фильтрация по модулю и команде |
| режим для гостей | real-time без авторизации | включается отдельно |
Частые ошибки
События не приходят вообще. Первым делом проверьте, в каком режиме работает модуль: без настроенного push-сервера это опрос с интервалом до минуты, и «мгновенность» получить нельзя в принципе.
Ключ подписи не совпадает. Сайт и push-сервер должны использовать одно значение, иначе соединение не установится.
Порты закрыты за балансировщиком. Служебные порты push-сервера должны быть доступны, иначе соединение не поднимется.
Обработчик ловит чужие события. Подписка без фильтра по модулю и команде получает всё подряд.
Через Pull пытаются передавать большие данные. Это канал уведомлений, а не транспорт: правильнее прислать идентификатор и признак изменения, а данные запросить обычным AJAX-запросом.
Полагаются на доставку как на гарантированную. Вкладка может быть закрыта, а соединение - прерваться. Важные вещи дублируйте состоянием на сервере.
Частые вопросы
Нужен ли отдельный push-сервер?
Без него модуль работает, но в режиме опроса: клиент обращается к серверу примерно раз в минуту, ускоряясь до десяти секунд, когда события идут. Для уведомлений это приемлемо, для настоящей мгновенности - нет, к тому же опрос создаёт лишнюю нагрузку на основной веб-сервер. Постоянное соединение требует настройки инфраструктуры, зато снимает и задержку, и нагрузку.
Как отправить событие группе пользователей?
Через механизм подписки на тег: пользователи подписываются на тег, а вы отправляете команду всем подписанным. Это удобнее перечисления идентификаторов, когда получатели заранее неизвестны - например, все, кто сейчас смотрит страницу заказа. Для конкретного адресата есть прямая отправка по идентификатору.
Что можно передавать в параметрах команды?
Небольшой набор данных, достаточный чтобы понять, что произошло: идентификатор объекта, тип изменения, новое значение счётчика. Полные данные через этот канал не гонят - получив уведомление, клиент запрашивает актуальное состояние обычным запросом. Так и канал не перегружается, и данные всегда свежие.
Можно ли использовать Pull для неавторизованных посетителей?
Да, режим для гостей существует и включается отдельно. Он полезен для витринных сценариев - обновление остатков, счётчик просмотров, live-уведомления в каталоге. Помните только, что гостевые подключения увеличивают число соединений с push-сервером, и это стоит учитывать при планировании нагрузки.
Связанные темы
- SMS и очереди - другие асинхронные механизмы
- Окружение - настройка push-сервера
- Ядро BX - события на клиенте
- Вебхуки и вызовы REST: настройка, права, разбор ошибок - доставка событий во внешние системы
- Push and Pull: настройка сервера очередей и проверка - включение и разбор обрывов
- Push and Pull - решения по мгновенным сообщениям
- Раздел Интеграции