WebSocket: примеры (JAVASCRIPT)
WebSocket(url (string), protocols (string, Array)): WebSocket Основы WebSocket в JavaScript
WebSocket представляет собой протокол связи, обеспечивающий полнодуплексный канал между клиентом и сервером через одно соединение. Технология применяется для приложений реального времени: чатов, торговых платформ, онлайн-игр и инструментов совместной работы.
Конструктор WebSocket принимает один обязательный и один опциональный аргумент:
- url (обязательный) - строка с адресом сервера по протоколам ws:// или wss://
- protocols (опциональный) - строка или массив строк с названиями подпротоколов
Конструктор возвращает объект WebSocket с состоянием подключения:
- CONNECTING (0) - соединение устанавливается
- OPEN (1) - соединение открыто
- CLOSING (2) - соединение закрывается
- CLOSED (3) - соединение закрыто
Основные методы объекта:
- send(data) - отправляет данные на сервер
- close(code, reason) - закрывает соединение
Простые примеры использования
Базовое подключение к серверу:
const socket = new WebSocket('wss://echo.websocket.org');
socket.onopen = function(event) {
console.log('Соединение установлено');
socket.send('Привет, сервер!');
};
socket.onmessage = function(event) {
console.log('Получено: ' + event.data);
};
socket.onclose = function(event) {
console.log('Соединение закрыто');
};Соединение установлено Получено: Привет, сервер!
Использование подпротокола:
const socket = new WebSocket('wss://server.com', ['soap', 'wamp']);
socket.onopen = function() {
console.log('Протокол: ' + socket.protocol);
};Протокол: soap
JavaScript-альтернативы
Server-Sent Events (EventSource) - односторонняя связь от сервера к клиенту. Подходит для уведомлений и обновлений в реальном времени. Не требует ответа от клиента.
Long Polling - эмуляция реального времени через HTTP-запросы. Клиент отправляет запрос, сервер держит соединение открытым до появления данных. После получения ответа клиент сразу отправляет новый запрос.
HTTP/2 Server Push - возможность сервера отправлять ресурсы клиенту до запроса. Эффективна для предзагрузки контента, но не для интерактивных приложений.
Реализации в других языках
Python (websockets):
import asyncio
import websockets
async def handler(websocket):
async for message in websocket:
await websocket.send(f'Ответ: {message}')
async def main():
async with websockets.serve(handler, 'localhost', 8765):
await asyncio.Future()
asyncio.run(main())PHP (Ratchet):
$app = new Ratchet\App('localhost', 8080);
$app->route('/chat', new MyChatComponent);
$app->run();C++ (Boost.Beast):
websocket::stream ws(ioc);
ws.accept();
ws.read(buffer);
ws.write(net::buffer('Сообщение')); Распространенные ошибки
Попытка отправки данных до открытия соединения:
const socket = new WebSocket('ws://server.com');
socket.send('данные'); // ОшибкаInvalidStateError: WebSocket is not open
Отсутствие обработки ошибок:
const socket = new WebSocket('ws://несуществующий-сервер');
socket.onopen = () => console.log('Открыто');
// onerror не установленИспользование неправильного формата данных:
const socket = new WebSocket('wss://server.com');
socket.onopen = () => {
socket.send({ key: 'value' }); // Объект не преобразован
};Данные не будут отправлены, требуется преобразование в строку
Изменения в спецификации
Современные реализации поддерживают бинарные данные через ArrayBuffer и Blob. Добавлена поддержка подпротоколов как массива строк. Улучшена обработка ошибок соединения. Появились возможности комбинирования с другими API, например, с WebRTC для передачи медиапотоков.
Расширенные сценарии работы
Работа с бинарными данными:
const socket = new WebSocket('wss://server.com');
socket.binaryType = 'arraybuffer';
socket.onmessage = function(event) {
if (event.data instanceof ArrayBuffer) {
const view = new Uint8Array(event.data);
console.log('Бинарные данные получены');
}
};
// Отправка бинарных данных
const buffer = new ArrayBuffer(16);
socket.send(buffer);Автоматическое переподключение:
class ReconnectingWebSocket {
constructor(url) {
this.url = url;
this.reconnectDelay = 1000;
this.connect();
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onclose = () => {
setTimeout(() => this.connect(), this.reconnectDelay);
};
}
}Обработка нескольких типов сообщений:
socket.onmessage = function(event) {
try {
const data = JSON.parse(event.data);
switch(data.type) {
case 'chat': handleChat(data.message); break;
case 'status': updateStatus(data.user); break;
case 'error': showError(data.code); break;
}
} catch(e) {
console.log('Не JSON сообщение:', event.data);
}
};