По умолчанию в битркис нет возможности отправлять сообщения по вебсокету гостям, но все же есть несколько действий которые необходимо выполнить, чтобы исправить это.
Код из примеров есть здесь - https://github.com/solopovsergey/dzen/tree/main/push_and_pull_for_guest
Про это же в официальной документации - https://dev.1c-bitrix.ru/learning/course/?COURSE_ID=43&CHAPTER_ID=05413&LESSON_PATH=3913.3516.4776.5413
Установка и настройка модулей
В первую очередь проверяем чтобы были установлены модули
- Push and Pull (pull)
- Веб-аналитика (statistic)
- REST API (rest)
Для примера будем использовать Push server облачный от 1С-Битрикс, доступный только для активной лицензии.
Определение идентификатора гостя
Далее добавляем обработчик события, в котором будем указывать идентификатор гостя для модуля Push and Pull. Модуль веб аналитики обеспечит нас этим идентификатором. Добавляем php код в файл /bitrix/php_interface/init.php
$eventManager = \Bitrix\Main\EventManager::getInstance();
//для автоподключения
$eventManager->addEventHandler(
"pull",
"OnGetDependentModule",
["CSolopovSergeyDzenPushAndPullForGuest", 'pullOnGetDependentModule']
);
// для установки идентификатора для гостя
$eventManager->addEventHandler(
"main",
"OnProlog",
["CSolopovSergeyDzenPushAndPullForGuest", 'mainOnProlog'],
2
);
class CSolopovSergeyDzenPushAndPullForGuest
{
const MODULE_ID = 'bxmaker.authuserphone';
public static function pullOnGetDependentModule()
{
return [
'MODULE_ID' => self::MODULE_ID,
'USE' => ["PUBLIC_SECTION"],
];
}
public static function mainOnProlog()
{
global $USER;
//сразу подключим библиотеку для клиентской стороны,
// можно перенести в header.php шаблона сайта
\Bitrix\Main\UI\Extension::load('pull.client');
// проверим чтобы еще не был определен
if (defined('PULL_USER_ID')) {
return;
}
// проверим чтобы польвзаотель был не атворизован
if ($USER->IsAuthorized()) {
return;
}
// обычная загрузка страницы, берем идентфикиатор от модуля веб аналитики (он уникальный)
if (isset($_SESSION['SESS_GUEST_ID'])) {
define('PULL_USER_ID', -1 * abs($_SESSION['SESS_GUEST_ID']));
return;
}
// загрузка парамтеров конфигурации для push&pull в котором отклчюен учет статистики
// используется при загрузке конфигурации, перемменная $_SESSION['SESS_GUEST_ID'] в запросе таком отсутствует
$req = \Bitrix\Main\Application::getInstance()->getContext()->getRequest();
if ((int)$req->getCookie('GUEST_ID')) {
define('PULL_USER_ID', -1 * (int)$req->getCookie('GUEST_ID'));
}
}
/**
* Вернет идентфикиатор получателя уведомления для текущего пользователя
* в зависимости от авторизованности пользователя
* @return int|null
*/
public static function getPullUserId()
{
if (defined('PULL_USER_ID')) {
return constant('PULL_USER_ID');
}
if (is_object($GLOBALS['USER'])) {
return (int)$GLOBALS['USER']->GetID();
}
return null;
}
/**
* Отправка получателю команду с парамтерами
* @param string $command
* @param array $arParams
* @param int $recipientId - получен от метода getPullUserId()
* @return bool
* @throws \Bitrix\Main\LoaderException
*/
public static function sendCommand($recipientId, $command, $arParams = [])
{
if (!\Bitrix\Main\Loader::includeModule('pull')) {
return false;
}
if (!\CPullOptions::GetNginxStatus()) {
return false;
}
$arMessage = [
'module_id' => self::MODULE_ID,
'command' => $command,
'params' => $arParams,
];
$result = \Bitrix\Pull\Event::add($recipientId, $arMessage);
if (!$result) {
//..
}
return true;
}
}
Проверка работы на клиенте
Чтобы проверить работу на клиенте, нужно в консоли браузера выполнить команду
BX.PULL.getDebugInfo();
Вывод должен быть примерно таким
Ошибка - Config is not loaded
Если в выводе вы видите ошибку - Config error: config is not loaded
необходимо в файл /urlrewrite.php добавить следующий код
array (
'CONDITION' => '#^/rest/#',
'RULE' => '',
'ID' => NULL,
'PATH' => '/bitrix/services/rest/index.php',
'SORT' => 10,
),
Сохраняем сделанные изменения, после этого нужно перезагрузить страницу и проверить заново - все должно работать.
Если не помогло, то нужно переключить в настройках модуля push and pull на использование локального сервера, сохранить и затем обратно вернуть на использование облачного варианта.
Получение сообщений в браузере
Для получения сообщения в браузере, добавляем следующий js код на страницу
BX.PULL.subscribe({
moduleId: 'main', // нужно заменить на свое значение,
command: 'hello',
callback: function (params, extra, command) {
alert('Получено сообщение по websocket, подробности в консоли браузера');
console.warn('Receive message:', params.message.text)
}.bind(this)
});
Отправка сообщений с сервера
Теперь для отправки сообщений по вебсокету в браузер пользователя (клиенту) можно воспользоваться методом
\CSolopovSergeyDzenPushAndPullForGuest::sendCommand(
\CSolopovSergeyDzenPushAndPullForGuest::getPullUserId(),
'hello',
[ 'time' => time() , 'text' => 'world' ]
);
или без обертки
if (\Bitrix\Main\Loader::includeModule('pull') && \CPullOptions::GetNginxStatus()) {
$userId = 0;
if (defined('PULL_USER_ID')) {
$userId = constant('PULL_USER_ID');
} elseif (is_object($GLOBALS['USER'])) {
$userId = (int)$GLOBALS['USER']->GetID();
}
$arMessage = [
'module_id' => 'main',
'command' => 'hello',
'params' => [
'time' => time(),
'text' => 'world'
],
];
$result = \Bitrix\Pull\Event::add($userId, $arMessage);
if (!$result) {
//.. error
}
}