WebSocket на JavaScript: создаём real-time приложения с Node.js

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

WebSocket на JavaScript: создаём real-time приложения с Node.js

Современные веб-приложения требуют мгновенного обмена данными между клиентом и сервером. Традиционный HTTP-протокол, основанный на запросах-ответах, плохо подходит для задач, где важна скорость: онлайн-чаты, биржевые котировки, многопользовательские игры или системы уведомлений. Именно здесь на помощь приходит протокол WebSocket. В этой статье мы разберём, как работает WebSocket на JavaScript, и создадим простое real-time приложение на Node.js.

Что такое WebSocket и зачем он нужен?

WebSocket — это протокол полнодуплексной связи (full-duplex) поверх TCP-соединения. В отличие от HTTP, где клиент всегда инициирует запрос, WebSocket позволяет серверу самостоятельно отправлять данные клиенту в любой момент. Это достигается за счёт установки постоянного двустороннего канала после первоначального handshake.

Основные преимущества WebSocket перед HTTP:

  • Низкая задержка — данные передаются мгновенно без повторных HTTP-заголовков.
  • Экономия трафика — минимальный служебный оверхед после установки соединения.
  • Постоянное соединение — нет необходимости в polling или long-polling.
  • Двусторонняя связь — сервер может инициировать отправку данных.

WebSocket идеально подходит для real-time приложений: чаты, уведомления, совместное редактирование документов, финансовые терминалы и онлайн-игры.

Установка и настройка WebSocket сервера на Node.js

Для работы с WebSocket на Node.js мы будем использовать популярную библиотеку ws. Она легковесна, надёжна и хорошо документирована.

Начнём с установки:

npm init -y
npm install ws

Теперь создадим простой сервер WebSocket, который будет принимать соединения и отвечать на сообщения:

// server.js
const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', function connection(ws) {
    console.log('Клиент подключился');

    // Отправляем приветственное сообщение
    ws.send('Добро пожаловать на WebSocket сервер!');

    // Обрабатываем входящие сообщения
    ws.on('message', function incoming(message) {
        console.log('Получено: %s', message);
        // Отправляем ответ всем подключенным клиентам
        wss.clients.forEach(function each(client) {
            if (client.readyState === WebSocket.OPEN) {
                client.send(`Эхо: ${message}`);
            }
        });
    });

    // Обрабатываем закрытие соединения
    ws.on('close', function close() {
        console.log('Клиент отключился');
    });
});

console.log('WebSocket сервер запущен на ws://localhost:8080');

Запустите сервер командой node server.js. Сервер готов принимать подключения.

Создание клиентской части на JavaScript

Клиентская часть работает прямо в браузере. WebSocket API встроен во все современные браузеры, поэтому никаких дополнительных библиотек не требуется.

Создадим HTML-страницу с простым интерфейсом:

<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Чат</title>
    <style>
        #messages { height: 300px; overflow-y: scroll; border: 1px solid #ccc; padding: 10px; margin-bottom: 10px; }
        #input { width: 300px; }
    </style>
</head>
<body>
    <h2>Real-time Чат</h2>
    <div id="messages"></div>
    <input type="text" id="input" placeholder="Введите сообщение..." />
    <button onclick="sendMessage()">Отправить</button>

    <script>
        // Подключаемся к WebSocket серверу
        const socket = new WebSocket('ws://localhost:8080');

        // Обработчик открытия соединения
        socket.addEventListener('open', function (event) {
            addMessage('Соединение установлено');
        });

        // Обработчик получения сообщения
        socket.addEventListener('message', function (event) {
            addMessage('Сервер: ' + event.data);
        });

        // Обработчик ошибок
        socket.addEventListener('error', function (event) {
            addMessage('Ошибка: ' + event.message);
        });

        // Обработчик закрытия соединения
        socket.addEventListener('close', function (event) {
            addMessage('Соединение закрыто');
        });

        function sendMessage() {
            const input = document.getElementById('input');
            const message = input.value;
            if (message) {
                socket.send(message);
                addMessage('Вы: ' + message);
                input.value = '';
            }
        }

        function addMessage(text) {
            const messages = document.getElementById('messages');
            const p = document.createElement('p');
            p.textContent = text;
            messages.appendChild(p);
            messages.scrollTop = messages.scrollHeight;
        }
    </script>
</body>
</html>

Откройте эту HTML-страницу в браузере. Вы увидите, что сообщения мгновенно отправляются на сервер и возвращаются обратно всем подключенным клиентам.

Расширенный пример: комнаты и broadcast

В реальных приложениях часто требуется разделять пользователей по комнатам (например, чаты). Давайте реализуем эту логику на сервере.

// advanced-server.js
const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8080 });
const rooms = new Map(); // roomName -> Set of WebSocket connections

wss.on('connection', function connection(ws) {
    let currentRoom = null;

    ws.on('message', function incoming(message) {
        const data = JSON.parse(message);

        switch (data.type) {
            case 'join':
                // Покидаем предыдущую комнату
                if (currentRoom && rooms.has(currentRoom)) {
                    rooms.get(currentRoom).delete(ws);
                    if (rooms.get(currentRoom).size === 0) {
                        rooms.delete(currentRoom);
                    }
                }
                // Входим в новую комнату
                currentRoom = data.room;
                if (!rooms.has(currentRoom)) {
                    rooms.set(currentRoom, new Set());
                }
                rooms.get(currentRoom).add(ws);
                ws.send(JSON.stringify({ type: 'system', message: `Вы вошли в комнату ${currentRoom}` }));
                broadcast(currentRoom, { type: 'system', message: 'Новый пользователь присоединился' }, ws);
                break;

            case 'message':
                if (currentRoom) {
                    broadcast(currentRoom, { type: 'message', user: data.user, text: data.text }, ws);
                }
                break;

            case 'leave':
                if (currentRoom && rooms.has(currentRoom)) {
                    rooms.get(currentRoom).delete(ws);
                    broadcast(currentRoom, {                

Блоги

Рекомендаций по книгам