Короткий ответ: в JavaScript WebSocket создается через new WebSocket(url). После события open можно отправлять сообщения через send, ответы приходят в событие message, а закрытие обрабатывается через close
Минимальный клиент:
const socket = new WebSocket("ws://localhost:8080");
socket.addEventListener("open", () => {
console.log("connected");
socket.send("hello");
});
socket.addEventListener("message", (event) => {
console.log("message:", event.data);
});
socket.addEventListener("close", () => {
console.log("closed");
});
Отправка JSON
В реальных приложениях чаще отправляют не простую строку, а JSON:
socket.addEventListener("open", () => {
socket.send(JSON.stringify({
type: "chat_message",
payload: {
text: "Привет",
roomId: "general",
},
}));
});
При получении:
socket.addEventListener("message", (event) => {
try {
const message = JSON.parse(event.data);
console.log(message.type, message.payload);
} catch {
console.log("Пришло не JSON-сообщение:", event.data);
}
});
try/catch нужен обязательно: WebSocket может получить невалидную строку, бинарные данные или сообщение старого формата
Проверка readyState
Перед отправкой проверяйте состояние:
function sendJson(socket, data) {
if (socket.readyState !== WebSocket.OPEN) {
return false;
}
socket.send(JSON.stringify(data));
return true;
}
Значения:
0 CONNECTING
1 OPEN
2 CLOSING
3 CLOSED
Главное правило: send безопасен только при OPEN
Закрытие соединения
socket.close(1000, "User left page");
Код 1000 означает нормальное закрытие. Закрывайте соединение при logout, уходе со страницы или размонтировании компонента
Для страницы:
window.addEventListener("pagehide", () => {
socket.close(1000, "Page hidden");
});
Простое переподключение
WebSocket сам не восстанавливает соединение. Если это нужно приложению, добавьте reconnect:
function connect() {
const socket = new WebSocket("wss://example.com/ws");
socket.addEventListener("open", () => {
console.log("connected");
});
socket.addEventListener("close", () => {
setTimeout(connect, 1000);
});
return socket;
}
В production-коде добавьте ограничение попыток и увеличивающуюся задержку. Иначе при падении сервера тысячи клиентов начнут переподключаться каждую секунду и только усилят проблему
Бинарные сообщения
Если сервер присылает бинарные данные:
socket.binaryType = "arraybuffer";
socket.addEventListener("message", (event) => {
if (event.data instanceof ArrayBuffer) {
const bytes = new Uint8Array(event.data);
console.log(bytes.length);
}
});
Но для чатов, уведомлений и статусов чаще достаточно JSON
Где хранить socket в приложении
Для маленькой страницы можно держать socket в одном файле. Для приложения лучше сделать отдельный модуль или сервис:
export function createRealtimeClient(url) {
const socket = new WebSocket(url);
return {
send(data) {
if (socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify(data));
}
},
close() {
socket.close(1000, "Client closed");
},
};
}
Так код интерфейса не будет везде создавать новые соединения и терять контроль над ними
Частые ошибки
Первая ошибка — вызвать socket.send() сразу после new WebSocket(), не дождавшись open
Вторая ошибка — использовать ws:// на HTTPS-странице. В продакшене нужен wss://
Третья ошибка — не обрабатывать close. Соединение может оборваться, и интерфейс должен это показать или переподключиться
Четвертая ошибка — считать WebSocket заменой всем HTTP-запросам. Обычно HTTP нужен для загрузки данных и форм, а WebSocket — для live-событий
Пятая ошибка — хранить один глобальный сокет без понимания жизненного цикла. Если пользователь вышел из аккаунта, старый сокет нужно закрыть, иначе он может продолжить получать личные события
Самопроверка
Поднимите тестовый сервер, подключитесь из браузера, отправьте JSON {"type":"ping"} и получите ответ pong. Затем остановите сервер и проверьте, что сработал close или error
Что почитать дальше по WebSocket
Если нужен общий маршрут по теме, откройте рубрику WebSocket. Для соседних задач пригодятся эти разборы:
- Django: как подружить Celery с WebSocket
- Django: как сохранить биржевые данные, полученные по WebSocket
- FastAPI WebSocket: уведомления в браузер
- Fedora 43: как установить WebSocket сервер



