Як працює WebSocket?
Що таке WebSocket
WebSocket - це мережевий протокол, який створює постійне двостороннє з'єднання між клієнтом (браузером) і сервером по одному TCP-каналу.
На відміну від HTTP:
- HTTP - це запит-відповідь (клієнт завжди починає);
- WebSocket - це постійне з'єднання, де обидві сторони можуть надсилати дані в будь-який момент.
Основна ідея
Звичайний HTTP-запит:
Клієнт → Сервер: дай нові дані
Сервер → Клієнт: ось дані
(з'єднання закрито)WebSocket:
Клієнт ↔ Сервер: встановили з'єднання (1 раз)
Далі спілкуються напряму, без повторних запитівПриклад "на пальцях"
Уяви, що ти розмовляєш по телефону із сервером:
- HTTP - це як щоразу заново набирати номер, сказати одне речення і покласти слухавку.
- WebSocket - це як подзвонити один раз і говорити скільки завгодно - в обидва боки.
Як встановлюється з'єднання (handshake)
- Клієнт відкриває з'єднання:
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: <random-key>
Sec-WebSocket-Version: 13- Сервер відповідає:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: <hash-key>- Після цього HTTP-з'єднання "апгрейдиться" у WebSocket. Тепер це не HTTP, а постійний двосторонній канал по TCP.
Як виглядає робота на клієнті (у браузері)
Приклад:
// Створюємо з'єднання
const socket = new WebSocket('wss://example.com/chat');
// Коли з'єднання встановлено
socket.addEventListener('open', () => {
console.log('З\'єднання відкрито');
socket.send('Привіт, сервере!');
});
// Коли приходять повідомлення
socket.addEventListener('message', (event) => {
console.log('Отримано повідомлення:', event.data);
});
// При помилці
socket.addEventListener('error', (err) => {
console.error('Помилка:', err);
});
// Коли з'єднання закрито
socket.addEventListener('close', () => {
console.log('З\'єднання закрито');
});Префікс ws:// або wss:// (аналог http і https):
ws://- без шифруванняwss://- захищене з'єднання (через TLS)
Як працює сервер (на Node.js)
Приклад з бібліотекою ws:
import { WebSocketServer } from 'ws';
const wss = new WebSocketServer({ port: 8080 });
wss.on('connection', (ws) => {
console.log('Клієнт підключений');
ws.on('message', (msg) => {
console.log('Отримано:', msg.toString());
ws.send(`Ти сказав: ${msg}`);
});
ws.on('close', () => console.log('Клієнт відключився'));
});Тепер будь-який клієнт може підключитися:
const socket = new WebSocket('ws://localhost:8080');Що робить WebSocket "живим"
WebSocket залишається відкритим, поки:
- з'єднання не перерветься;
- одна зі сторін не викличе
.close(); - не станеться таймаут/помилка мережі.
Браузер і сервер можуть періодично надсилати "пінги" (ping/pong), щоб перевірити, що з'єднання живе.
Формат повідомлень
WebSocket передає дані у бінарному або текстовому вигляді.
На клієнті event.data може бути:
stringBlobArrayBuffer
Можна навіть надсилати JSON:
socket.send(JSON.stringify({ type: 'chat', text: 'Привіт!' }));Чому WebSocket кращий за HTTP-полінг
| Спосіб | Що робить | Мінуси |
|---|---|---|
| Polling | клієнт кожні X секунд робить fetch() | затримки, зайві запити |
| Long Polling | клієнт тримає запит "відкритим" до відповіді | висока нагрузка на сервер |
| WebSocket | одне постійне з'єднання, двостороннє | складніша реалізація, потрібен сервер із підтримкою WS |
Підтримка
Працює у всіх сучасних браузерах
(Chrome, Firefox, Safari, Edge, Opera, Node.js)
і навіть у хмарних функціях і WebWorkers.
Де використовується WebSocket
- Чати та месенджери (Telegram Web, Slack, Discord)
- Торгові термінали і біржі (реальний час)
- Онлайн-ігри
- Live-сповіщення (push-події)
- Спільне редагування документів (Google Docs)
- Трекінг геопозиції в реальному часі
Підсумок
| Що | Опис |
|---|---|
| Тип протоколу | Двосторонній, поверх TCP |
| URL-схема | ws:// або wss:// |
| Головна відмінність від HTTP | Постійне з'єднання і можливість надсилати дані з обох сторін |
| Підтримка | Усі сучасні браузери |
| Типові застосування | Чати, онлайн-ігри, сповіщення, біржі |
Підсумовуючи:
WebSocket = постійний, двосторонній, асинхронний канал зв'язку між браузером і сервером.
Він зберігає з'єднання відкритим і дозволяє обмінюватися даними в реальному часі, без перезавантаження сторінки і без постійних HTTP-запитів.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.