Короткий ответ: поддержку WebSockets нужно включить на трех уровнях: в backend-приложении, в reverse proxy и в сетевой конфигурации. Backend должен иметь WebSocket endpoint, proxy должен пропускать Upgrade-заголовки, а firewall и домен должны позволять подключиться по ws:// или wss://
Уровень 1: backend
Сначала приложение должно уметь принимать WebSocket:
const { WebSocketServer } = require("ws");
const wss = new WebSocketServer({ port: 8080 });
wss.on("connection", (socket) => {
socket.send("connected");
});
Если backend не поднимает WebSocket endpoint, Nginx и firewall не помогут
Уровень 2: reverse proxy
Для Nginx:
location /ws {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
Ключевые строки — Upgrade и Connection. Без них запрос не перейдет в WebSocket
Уровень 3: wss
Если сайт работает по HTTPS, WebSocket должен быть:
wss://example.com/ws
а не:
ws://example.com/ws
TLS обычно настраивается на reverse proxy
Уровень 4: firewall и порты
Если подключение идет напрямую к порту:
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
Но для production чаще открывают только 80/443, а WebSocket-приложение прячут за Nginx
Уровень 5: приложение клиента
На клиенте тоже нужно правильно выбрать адрес:
const protocol = window.location.protocol === "https:" ? "wss" : "ws";
const socket = new WebSocket(`${protocol}://${window.location.host}/ws`);
Если адрес зашит как ws://localhost:8080, после публикации сайт будет пытаться подключиться к компьютеру пользователя, а не к вашему серверу
Таймауты proxy
Для долгих соединений проверьте таймауты reverse proxy. Если proxy закрывает соединение каждые 60 секунд, приложение будет постоянно переподключаться. Увеличьте read timeout и добавьте heartbeat на уровне приложения или сервера
proxy_read_timeout 3600s;
Настройки зависят от инфраструктуры, но симптом один: соединение открывается и стабильно закрывается через одинаковый интервал
Что проверить в хостинге
На shared-хостинге WebSocket может быть запрещен или ограничен. Перед настройкой проверьте:
- можно ли запускать долгоживущие процессы;
- поддерживает ли proxy Upgrade;
- доступен ли
wss://; - можно ли открыть нужный endpoint;
- не убивает ли хостинг процесс по таймауту.
Если ответов нет, проще использовать VPS или платформу, где WebSocket официально поддерживается
Проверка
В браузере:
const socket = new WebSocket("wss://example.com/ws");
socket.onopen = () => console.log("open");
socket.onerror = () => console.log("error");
В DevTools откройте Network -> WS и проверьте, появился ли WebSocket-запрос
Частые ошибки
Первая ошибка — включить backend, но забыть proxy Upgrade
Вторая ошибка — открыть порт, но подключаться к неправильному path
Третья ошибка — использовать ws:// на HTTPS-странице
Четвертая ошибка — думать, что WebSockets включаются одной галочкой. Обычно это цепочка: backend, proxy, TLS, firewall
Пятая ошибка — не проверять путь /ws. Даже если домен правильный, endpoint может быть другим: /socket, /realtime, /api/ws
Шестая ошибка — пытаться включить WebSocket только на frontend. Если backend и proxy не готовы, браузерный код ничего не исправит
Итоговая рабочая схема
Для большинства сайтов нормальная схема выглядит так: браузер подключается к wss://domain/ws, Nginx принимает HTTPS и передает соединение во внутренний backend, а backend уже держит WebSocket-сессию. Пользователь не видит внутренний порт, а сертификат и домен остаются на стороне proxy
Если поддержку включает несколько человек, удобно разделить зоны ответственности. Backend-разработчик отвечает за endpoint и формат сообщений, администратор — за Nginx, TLS и firewall, frontend-разработчик — за правильный адрес, обработку open, message, error, close и переподключение. Тогда фраза "WebSocket не работает" быстро превращается в конкретную проверку уровня
Самопроверка
Проверьте локально ws://localhost:8080, затем через proxy ws://domain/ws, затем через TLS wss://domain/ws. Так проще понять, на каком уровне ломается подключение
Что почитать дальше по WebSocket
Если нужен общий маршрут по теме, откройте рубрику WebSocket. Для соседних задач пригодятся эти разборы:
- Django: как подружить Celery с WebSocket
- Django: как сохранить биржевые данные, полученные по WebSocket
- FastAPI WebSocket: уведомления в браузер
- Fedora 43: как установить WebSocket сервер