WebSocket: примеры (JAVASCRIPT)

Использование WebSocket в JavaScript на практике
Раздел: Сетевые запросы, WebSocket
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 для передачи медиапотоков.

Расширенные сценарии работы

Работа с бинарными данными:

Пример javascript
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);

Автоматическое переподключение:

Пример javascript
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);
    };
  }
}

Обработка нескольких типов сообщений:

Пример javascript
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);
  }
};

JS WebSocket function comments

En
WebSocket Creates a WebSocket connection