API WebSocket: открытие, сообщение, закрытие и ошибка
Создайте соединение WebSocket, отправляйте и принимайте сообщения в обработчике события message и обрабатывайте ошибки соединения и корректное закрытие
«API WebSocket: открытие, сообщение, закрытие и ошибка» — бесплатный урок Frontend Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Frontend Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Frontend Academy содержит 4 уроков всего.
Зачем нужны WebSockets?
HTTP работает по схеме «запрос–ответ». Для приложений, работающих в реальном времени (чатов, многопользовательских игр, оперативных обновлений), нужна постоянная двусторонняя связь. WebSockets создают одно TCP-соединение, которое остаётся открытым и позволяет обеим сторонам отправлять сообщения в любой момент.
Создание WebSocket
Создайте WebSocket с URL-адресом ws:// или wss://. Браузер самостоятельно выполняет рукопожатие для обновления соединения.
const ws = new WebSocket('wss://api.example.com/realtime');
// Always use wss:// (secure) in productionЧетыре события
WebSocket поддерживает четыре типа событий: open (соединение установлено), message (данные получены), close (соединение завершено), error (произошла проблема).
ws.addEventListener('open', () => {
console.log('Connected');
ws.send(JSON.stringify({ type: 'subscribe', channel: 'updates' }));
});
ws.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
console.log('Received:', data);
});
ws.addEventListener('close', (event) => {
console.log('Closed:', event.code, event.reason);
});
ws.addEventListener('error', (event) => {
console.error('Error:', event);
});Отправка сообщений
Используйте ws.send(). Метод принимает строки, ArrayBuffers, двоичные объекты или ArrayBufferView. Для структурированных данных сначала вызовите JSON.stringify.
ws.send('hello');
ws.send(JSON.stringify({ type: 'chat', text: 'Hi' }));
// Binary:
const buffer = new ArrayBuffer(8);
ws.send(buffer);Получение сообщений
Проверьте event.data — его тип соответствует тому, что отправил сервер. Для объектов используйте JSON.parse.
ws.addEventListener('message', (event) => {
// typeof event.data: string | ArrayBuffer | Blob
if (typeof event.data === 'string') {
const msg = JSON.parse(event.data);
handleMessage(msg);
}
});Состояние соединения (readyState)
Проверьте ws.readyState: CONNECTING=0, OPEN=1, CLOSING=2, CLOSED=3. Не отправляйте данные до перехода в состояние OPEN.
if (ws.readyState === WebSocket.OPEN) {
ws.send(message);
} else {
console.warn('Not connected yet');
}Корректное закрытие
Вызовите ws.close(code, reason). Стандартные коды закрытия: 1000 (нормальное закрытие), 1001 (уход со страницы), 1008 (нарушение политики), 1011 (ошибка сервера).
ws.close(1000, 'User logged out');Стратегия переподключения
WebSockets отключаются при изменении сети, перезапуске сервера и в других подобных ситуациях. Реализуйте переподключение с экспоненциальной задержкой.
let reconnectDelay = 1000;
function connect() {
const ws = new WebSocket('wss://api/realtime');
ws.addEventListener('open', () => { reconnectDelay = 1000; });
ws.addEventListener('close', () => {
setTimeout(connect, reconnectDelay);
reconnectDelay = Math.min(reconnectDelay * 2, 30000);
});
return ws;
}Контрольные сигналы и поддержание соединения
Простои WebSockets могут привести к отключению прокси-сервером или балансировщиком нагрузки примерно через 60 секунд. Отправляйте контрольный сигнал каждые 25–30 секунд, чтобы соединение оставалось активным.
let pingInterval;
ws.addEventListener('open', () => {
pingInterval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'ping' }));
}
}, 25000);
});
ws.addEventListener('close', () => clearInterval(pingInterval));Аутентификация
WebSockets не поддерживают пользовательские заголовки. Варианты: 1) передать токен аутентификации в строке запроса (?token=jwt) URL-адреса WS; 2) отправить сообщение аутентификации после события open; 3) использовать cookie (для одного источника это работает автоматически).
// Query string:
const ws = new WebSocket(`wss://api/realtime?token=${jwt}`);
// Auth message:
ws.addEventListener('open', () => {
ws.send(JSON.stringify({ type: 'auth', token: jwt }));
});Хук React для WebSockets
Инкапсулируйте жизненный цикл WS в пользовательском хуке, чтобы избежать утечки соединений.
function useWebSocket(url) {
const [messages, setMessages] = useState([]);
const wsRef = useRef(null);
useEffect(() => {
const ws = new WebSocket(url);
wsRef.current = ws;
ws.addEventListener('message', (e) => {
setMessages(m => [...m, JSON.parse(e.data)]);
});
return () => ws.close();
}, [url]);
return { messages, send: (msg) => wsRef.current?.send(JSON.stringify(msg)) };
}WebSocket, HTTP/2 и SSE
WebSocket: полнодуплексная связь, данные могут отправлять обе стороны. Серверная отправка в HTTP/2: устарела. Server-Sent Events: только от сервера к клиенту, проще и с автоматическим переподключением. Выбирайте WS, когда клиенту тоже нужно отправлять данные (например, в чате), а SSE — для односторонних уведомлений.
Быстрая проверка
Какой стандартный код закрытия WebSocket используется для нормального преднамеренного закрытия (например, когда пользователь вышел из системы)?
Повторение: API WebSocket
new WebSocket('wss://...') открывает соединение. Четыре события: open, message, close, error. send() принимает строку, ArrayBuffer или Blob; для объектов используйте JSON.stringify. Проверяйте readyState перед отправкой. Для корректного закрытия используйте close(1000). Выполняйте переподключение с экспоненциальной задержкой. Отправляйте контрольный сигнал каждые 25 секунд, чтобы соединение оставалось активным. Аутентификация выполняется через строку запроса или сообщение аутентификации. В React оберните всё в хук.
Часто задаваемые вопросы
Урок «API WebSocket: открытие, сообщение, закрытие и ошибка» бесплатный?
Да — полный текст урока «API WebSocket: открытие, сообщение, закрытие и ошибка» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Frontend Academy, подпишись на CoddyKit PRO. Курс Frontend Academy содержит 4 уроков всего.
Чему я научусь в уроке «API WebSocket: открытие, сообщение, закрытие и ошибка»?
Создайте соединение WebSocket, отправляйте и принимайте сообщения в обработчике события message и обрабатывайте ошибки соединения и корректное закрытие Ты практикуешь Frontend Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Frontend Academy?
Предыдущий опыт не требуется. Frontend Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «API WebSocket: открытие, сообщение, закрытие и ошибка»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Frontend Academy?
Да. Каждый урок Frontend Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- API WebSocket: открытие, сообщение, закрытие и ошибка
- Интеграция клиента Socket.io
- Server-Sent Events для однонаправленной потоковой передачи
- Шаблоны интерфейсов реального времени