Настройка веб-сокетов для 1С-Битрикс
WebSocket — протокол постоянного двустороннего соединения между браузером и сервером. Без WebSocket чат в Битрикс работает через Long Polling: браузер каждые 20 секунд спрашивает «есть новые сообщения?». С WebSocket сервер отправляет сообщение мгновенно, как только оно появилось. Для корпоративного портала, онлайн-чата и уведомлений реального времени — принципиальная разница.
Как Битрикс использует WebSocket
Модуль pull (Push and Pull) при наличии NodeJS push-сервера автоматически переключается с Long Polling на WebSocket. Клиентская часть — JS-библиотека BX.PullClient, которая пробует WebSocket первым, при неудаче откатывается на SSE, затем на Long Polling.
Транспорт определяется в bitrix/js/pull/pull.js через переменную BX.Pull.config. Принудительно установить транспорт для отладки:
BX.Pull.connect({
serverEnabled: true,
serverUrl: 'https://example.ru/bitrix/subws/',
guestMode: false,
userId: USER_ID,
userHash: USER_HASH,
transport: 'websocket' // принудительно WebSocket
});
Nginx: правильная конфигурация WebSocket-прокси
WebSocket требует специальной обработки в Nginx. Ключевое — заголовки Upgrade и Connection:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl http2;
server_name example.ru;
# ... SSL настройки ...
# WebSocket endpoint для push-server
location /bitrix/subws/ {
proxy_pass http://127.0.0.1:9011;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Критически важно: без этого Nginx разрывает соединение через 60 сек
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
# Не буферизировать — данные должны идти в реальном времени
proxy_buffering off;
}
}
map $http_upgrade $connection_upgrade — корректная обработка как WebSocket (Upgrade: websocket), так и обычных HTTP-запросов через один location.
Лимиты соединений
Каждое WebSocket-соединение — это открытый файловый дескриптор на уровне ОС. При 2000 онлайн-пользователей — 2000 дескрипторов только от WebSocket.
Системные лимиты:
# Текущий лимит
ulimit -n
# Увеличить для текущей сессии
ulimit -n 65535
# Постоянно через /etc/security/limits.conf
cat >> /etc/security/limits.conf << 'EOF'
www-data soft nofile 65535
www-data hard nofile 65535
nginx soft nofile 65535
nginx hard nofile 65535
EOF
# Для systemd-сервисов
# В /etc/systemd/system/nginx.service.d/override.conf:
[Service]
LimitNOFILE=65535
Nginx worker_connections:
events {
worker_connections 10240;
use epoll; # Linux — самый эффективный метод
multi_accept on; # принимать несколько соединений за один вызов
}
NodeJS push-server: кластерный режим
Один NodeJS-процесс использует одно ядро CPU. При высокой нагрузке (1000+ соединений) нужен кластерный режим — несколько worker-процессов за load balancer:
В config.json push-server:
{
"cluster": {
"workers": 4,
"sticky": true
}
}
sticky: true — «липкие» соединения: один клиент всегда попадает на один worker. Без этого WebSocket-соединение может разорваться при переключении между воркерами.
Для балансировки нескольких NodeJS-инстансов в Nginx:
upstream push_backend {
ip_hash; # sticky sessions по IP
server 127.0.0.1:9011;
server 127.0.0.1:9012;
server 127.0.0.1:9013;
server 127.0.0.1:9014;
}
location /bitrix/subws/ {
proxy_pass http://push_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
proxy_buffering off;
}
Отладка WebSocket-соединения
В Chrome DevTools → Network → фильтр WS — показывает все WebSocket-соединения с данными фреймов.
Через curl (только handshake):
curl -v \
-H "Upgrade: websocket" \
-H "Connection: Upgrade" \
-H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
-H "Sec-WebSocket-Version: 13" \
https://example.ru/bitrix/subws/
# Ожидаемый ответ: HTTP/1.1 101 Switching Protocols
Типовые проблемы
Соединение разрывается каждые 60 секунд. proxy_read_timeout в Nginx не выставлен или равен умолчанию (60s). WebSocket keepalive не успевает.
WebSocket не работает за Cloudflare. Cloudflare проксирует WebSocket только на платных тарифах (Pro+). На бесплатном тарифе — использовать long polling или выводить WebSocket-домен из-под Cloudflare (DNS-only).
Ошибка 400 Bad Request при handshake. Nginx не передаёт заголовок Upgrade бэкенду — проверить наличие proxy_http_version 1.1 и proxy_set_header Upgrade. HTTP/2 не поддерживает WebSocket upgrade — для WebSocket endpoint использовать только HTTP/1.1.







