Сайты и приложения
Хостинг для WebSocket: чат, онлайн-игра или живые обновления
Коротко
Для WebSocket нужен хостинг, на котором сервер работает постоянно и держит долгие соединения, а не запускается на один короткий запрос. Чат, онлайн-игра или живая лента должны слушать адрес 0.0.0.0 и порт из переменной PORT, а браузер — подключаться по защищённому адресу wss:// и уметь переподключаться после обрыва. На платформах вроде Netrun WebSocket работает через ту же ссылку с HTTPS, что и сайт, без отдельной настройки сервера. Для того, что должно быть онлайн всегда, берите тариф Pro.
- WebSocket-соединение начинается как обычный HTTP-запрос с заголовком Upgrade и остаётся открытым, пока его не закроет одна из сторон.
- Страница, открытая по HTTPS, может подключаться только к адресу wss://, потому что браузер блокирует незащищённый ws:// как смешанное содержимое.
- Встроенный в браузер WebSocket не переподключается после обрыва сам, а клиент Socket.IO делает это автоматически.
- Uvicorn принимает WebSocket-соединения только при установленном пакете websockets или wsproto, например через uvicorn[standard].
- У Vercel поддержка WebSocket в функциях находится в бета-версии, и соединение закрывается, когда функция достигает максимальной длительности работы.
Обычный сайт отвечает на запрос и забывает о посетителе. Чату, онлайн-игре, доске с курсором соседа или ленте заказов нужно другое: соединение, которое остаётся открытым, чтобы сервер мог сам прислать новое сообщение в ту же секунду. Для этого и существует WebSocket. Код на нём пишется за вечер, а сложности начинаются при публикации: локально всё работало, а на хостинге соединение не открывается или рвётся каждые несколько минут.
Почти всегда причина не в коде, а в том, где и как он запущен. Короткие бессерверные функции рассчитаны на быстрые ответы, браузер на HTTPS-странице не пустит незащищённое соединение, а сервер, который слушает только localhost, снаружи не виден вовсе — об этом подробнее в разборе приложения, которое слушает localhost. Ниже — что нужно WebSocket-приложению от хостинга и как подготовить код.
| Критерий | Бессерверные функции | Платформа с постоянным процессом | Свой VPS |
|---|---|---|---|
| Как работает код | Функция запускается на запрос и завершается | Одна программа работает постоянно | Программа работает постоянно, всё вокруг настраиваете вы |
| Долгие соединения | Закрываются по лимиту длительности функции, если поддерживаются вообще | Держатся, пока работает процесс | Держатся, пока работает процесс |
| Комнаты и участники в памяти | Новое подключение может попасть в другой экземпляр, нужна внешняя база вроде Redis | Один процесс видит всех участников | Один процесс видит всех участников |
| Адрес wss:// и сертификат | Даёт платформа | Ссылка с HTTPS выдаётся сразу, wss:// работает через неё | Прокси и сертификат настраиваете сами |
| Что делаете вы | Переписываете сервер под модель функций | Загружаете код, слушаете 0.0.0.0 и PORT | Ставите систему, прокси, автозапуск и обновления |
| Подходит для | Коротких сессий в проекте, который уже живёт на этой платформе | Чатов, игр, живых дашбордов и уведомлений | Нестандартных задач, где нужен полный контроль над машиной |
Запустите сервер как постоянно работающую программу#
WebSocket-сервер — это программа, которая работает всё время и держит открытыми соединения всех участников. Подойдут FastAPI с uvicorn, Node.js с библиотекой ws, Socket.IO, Flask-SocketIO или Go. Для FastAPI проверьте, что в requirements.txt стоит uvicorn[standard] или пакет websockets: без них uvicorn принимает обычные запросы, но отказывает WebSocket-подключениям.
Слушайте 0.0.0.0 и порт из PORT#
Сервер должен слушать адрес 0.0.0.0 и порт из переменной окружения PORT. WebSocket не требует отдельного порта: он работает на том же порту и по той же ссылке, что и страницы сайта, а отличается только путём, например /ws. Если в коде жёстко прописан localhost или свой порт для сокетов, снаружи до него не достучаться.
Подключайтесь по wss:// с того же адреса#
Страница, открытая по HTTPS, может подключаться только к адресу wss://. Не прописывайте в коде клиента localhost и номер порта: собирайте адрес из текущего адреса страницы, тогда одна и та же сборка работает и у вас, и на хостинге. Если страница и сервер живут на разных адресах, сервер должен разрешать подключения с адреса страницы.
Добавьте переподключение и пинг#
Соединение обязательно когда-нибудь оборвётся: телефон сменил сеть, ноутбук уснул, сервер обновился. Встроенный в браузер WebSocket сам не переподключается, поэтому добавьте повторное подключение с растущей паузой и после него заново запрашивайте нужное состояние. Клиент Socket.IO переподключается сам. Многие прокси закрывают молчащие соединения, поэтому полезно раз в полминуты отправлять короткий пинг.
Не держите важное только в памяти#
Список участников комнаты можно держать в памяти процесса, но историю сообщений, счёт игры и заказы — нет: при обновлении кода или перезапуске память очищается. Сохраняйте их в базу, например SQLite в постоянной папке /data или PostgreSQL отдельным сервисом. И запускайте сервер одним рабочим процессом: у нескольких процессов память раздельная, и участники одной комнаты перестанут видеть друг друга.
Опубликуйте и проверьте с двух вкладок#
В Netrun вы загружаете код архивом, папкой или из GitHub, язык и команда запуска определяются сами, а на выходе получаете ссылку с HTTPS — WebSocket работает через неё же. Откройте приложение в двух вкладках или на двух устройствах и отправьте сообщение: оно должно появиться в обеих. Если не появилось, откройте живые логи проекта и консоль браузера — там будет видно, дошло ли подключение до сервера.
WebSocket-приложению нужно немного, но без компромиссов: постоянно работающий процесс, адрес с HTTPS для wss:// и клиент, который переживает обрывы. В Netrun всё это получается из обычного кода — без настройки прокси и сертификатов, с живыми логами и автоматическим перезапуском при падении. На бесплатном тарифе удобно проверить, что соединения открываются и сообщения доходят. Если чат, игра или дашборд должны быть онлайн постоянно, берите Pro. Попробовать Netrun.
Частые вопросы
Почему WebSocket работает у меня на компьютере, а на хостинге нет?
Чаще всего клиент подключается к ws://localhost или к жёстко прописанному порту, а на хостинге нужен адрес wss:// той же ссылки, что и у сайта. Вторая причина — сервер слушает 127.0.0.1 вместо 0.0.0.0. Для FastAPI добавьте ещё одну проверку: в зависимостях должен быть uvicorn[standard] или пакет websockets.
Можно ли держать WebSocket на Vercel или другом бессерверном хостинге?
У Vercel поддержка WebSocket сейчас в бета-версии: соединение закрывается, когда функция достигает максимальной длительности, а новые подключения могут попасть в другой экземпляр, поэтому общие комнаты приходится держать во внешней базе. Для коротких сессий это работает. Для чата или игры, где люди сидят часами, проще постоянно работающий сервер.
Нужен ли для WebSocket отдельный порт?
Нет. WebSocket-соединение начинается как обычный HTTP-запрос и работает на том же порту и по той же ссылке, что и сайт. Обычно для него выделяют отдельный путь, например /ws или /socket.io, а сервер слушает один порт из переменной PORT.
Что выбрать: Socket.IO или обычный WebSocket?
Socket.IO даёт комнаты, автоматическое переподключение и запасной вариант через обычные запросы, но требует своего клиента с обеих сторон. Обычный WebSocket — стандарт браузера, он легче и подключается из любого языка, а переподключение вы пишете сами. Для чата с комнатами удобнее Socket.IO, для простой живой ленты хватит обычного WebSocket.
Почему участники одной комнаты не видят сообщения друг друга?
Чаще всего сервер запущен несколькими рабочими процессами, и у каждого свой список подключений в памяти. Сообщение уходит только тем, кто подключён к тому же процессу. Запустите сервер одним процессом или передавайте сообщения между процессами через общую базу вроде Redis.
Как выложить сайт в интернет?
Загрузите код сайта ZIP-архивом или из GitHub — Netrun соберёт его и выдаст рабочую ссылку с HTTPS. Подойдёт статический сайт (HTML, CSS, JS), приложение на React или сайт на Python. Покупать домен, настраивать сервер и сертификаты не нужно.
Сохранятся ли данные при обновлении кода?
Да, если данные лежат в постоянном хранилище. У обычного проекта это папка /data: всё, что приложение туда сохранило, остаётся при обновлении кода и перезапуске, а посмотреть и скачать файлы можно на вкладке «Данные». Если вы описали сервисы сами в docker-compose, постоянное хранилище — это именованные тома из вашего файла, и папки /data у такого проекта нет. Файлы, записанные мимо хранилища, при следующей публикации создаются заново. Ссылка проекта в любом случае остаётся прежней.
Чем отличается тариф Pro?
На тарифе Pro проект работает круглосуточно: сайт не засыпает и отвечает мгновенно, без паузы на пробуждение, а бот или фоновый скрипт работает постоянно, без ограничения по времени. Кроме того, на Pro больше памяти, процессора и места, а к сайту можно подключить свои домены — столько, сколько нужно, каждый с HTTPS.