Socket.io для JavaScript (Node.js): полное руководство с примерами

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

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

Начать курс

Что такое Socket.io и зачем он нужен?

Socket.io — это мощная JavaScript-библиотека, которая обеспечивает real-time (реальное время) двунаправленную коммуникацию между клиентом (браузером) и сервером (Node.js). В отличие от традиционного HTTP-протокола, где клиент отправляет запрос и ждет ответа, Socket.io позволяет серверу самостоятельно инициировать отправку данных клиенту в любой момент, и наоборот.

Зачем это нужно? Представьте себе чат-приложение, онлайн-игру, панель мониторинга с живыми графиками или систему совместного редактирования документов. Во всех этих сценариях данные должны обновляться мгновенно, без перезагрузки страницы. HTTP для этого не подходит, так как он работает по принципу "запрос-ответ". Socket.io решает эту проблему, устанавливая постоянное соединение (обычно через WebSocket), по которому данные могут передаваться в обе стороны в любой момент.

Ключевые особенности Socket.io:

  • Двунаправленность: Сервер и клиент могут отправлять сообщения друг другу.
  • Real-time: Сообщения доставляются мгновенно (с минимальной задержкой).
  • Автоматическое переподключение: Если соединение обрывается, Socket.io сам пытается его восстановить.
  • Комнаты (Rooms): Возможность группировать клиентов и отправлять сообщения только определенной группе.
  • Пространства имен (Namespaces): Разделение приложения на независимые каналы связи.
  • Надежность: Если WebSocket не поддерживается, Socket.io автоматически переключается на другие методы (long-polling, FlashSocket и т.д.).

Установка Socket.io

Socket.io состоит из двух частей: серверной (для Node.js) и клиентской (для браузера). Обе устанавливаются через npm.

Установка серверной части

Откройте терминал в папке вашего проекта и выполните команду:

npm install socket.io

Установка клиентской части

Клиентский скрипт можно подключить двумя способами:

1. Через CDN (проще всего для начала):

<script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>

2. Через npm (для проектов со сборщиками, например, Webpack):

npm install socket.io-client

Быстрый старт: первый чат

Давайте создадим простейший чат, где сообщения от одного клиента видят все остальные.

Шаг 1: Сервер (файл server.js)

// server.js
const http = require('http');
const { Server } = require("socket.io");

// 1. Создаем HTTP сервер
const server = http.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Socket.io сервер запущен');
});

// 2. Создаем экземпляр Socket.io, привязанный к серверу
const io = new Server(server);

// 3. Обработчик подключения нового клиента
io.on('connection', (socket) => {
    console.log('Новый пользователь подключился:', socket.id);

    // 4. Слушаем событие 'chat message' от клиента
    socket.on('chat message', (msg) => {
        console.log('Сообщение:', msg);
        // 5. Отправляем сообщение ВСЕМ подключенным клиентам (включая отправителя)
        io.emit('chat message', msg);
    });

    // 6. Обработчик отключения клиента
    socket.on('disconnect', () => {
        console.log('Пользователь отключился:', socket.id);
    });
});

// 7. Запускаем сервер на порту 3000
server.listen(3000, () => {
    console.log('Сервер запущен на http://localhost:3000');
});

Шаг 2: Клиент (файл index.html)

<!DOCTYPE html>
<html>
<head>
    <title>Socket.io чат</title>
    <script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>
</head>
<body>
    <ul id="messages"></ul>
    <form id="form" action="">
        <input id="input" autocomplete="off" /><button>Отправить</button>
    </form>

    <script>
        // 1. Подключаемся к серверу
        const socket = io('http://localhost:3000');

        // 2. Получаем элементы DOM
        const form = document.getElementById('form');
        const input = document.getElementById('input');
        const messages = document.getElementById('messages');

        // 3. Обработчик отправки формы
        form.addEventListener('submit', (e) => {
            e.preventDefault();
            if (input.value) {
                // 4. Отправляем сообщение на сервер
                socket.emit('chat message', input.value);
                input.value = '';
            }
        });

        // 5. Слушаем событие 'chat message' от сервера
        socket.on('chat message', (msg) => {
            const item = document.createElement('li');
            item.textContent = msg;
            messages.appendChild(item);
            window.scrollTo(0, document.body.scrollHeight);
        });
    </script>
</body>
</html>

Шаг 3: Запуск

Запустите сервер командой:

node server.js

Откройте index.html в двух разных вкладках браузера. Теперь сообщения, отправленные в одной вкладке, будут мгновенно появляться в другой.

Основные методы и функции Socket.io

Рассмотрим ключевые методы, которые используются в 90% проектов. Методы разделены на серверные и клиентские.

Серверные методы (используются в server.js)

1. io.on('connection', callback)

Что делает: Это главное событие на сервере. Оно срабатывает каждый раз, когда новый клиент успешно подключается к серверу. Внутри колбэка вы получаете объект socket, который представляет подключение конкретного клиента.

Параметры:

  • 'connection' — строка, имя события (обязательно).
  • callback(socket) — функция, которая выполняется при подключении. Принимает объект socket.

Пример:

io.on('connection', (socket) => {
    console.log('Клиент подключился:', socket.id);
    // Здесь можно навешивать обработчики для этого конкретного клиента
    socket.on('some event', (data) => { /* ... */ });
});

2. io.emit(eventName, data)

Что делает: Отправляет сообщение (событие) всем подключенным клиентам одновременно. Это "глобальная рассылка".

Параметры:

  • eventName (String) — имя события, которое будут слушать клиенты.
  • data (Any) — данные, которые передаются вместе с событием. Может быть строкой, числом, объектом, массивом и т.д.

Пример:

// Сервер отправляет всем клиентам текущее время каждую секунду
setInterval(() => {
    const time = new Date().toLocaleTimeString();
    io.emit('server time', time);
}, 1000);

3. socket.emit(eventName, data)

Что делает: Отправляет сообщение только одному конкретному клиенту, который представлен этим объектом socket. Остальные клиенты это сообщение не получат.

Параметры:

  • eventName (String) — имя события.
  • data (Any) — данные.

Пример:

// Отправляем приветствие только что подключившемуся клиенту
io.on('connection', (socket) => {
    socket.emit('welcome', 'Добро пожаловать в чат!');
});

4. socket.broadcast.emit(eventName, data)

Что делает: Отправляет сообщение всем клиентам, кроме отправителя. Очень полезно для чатов, чтобы не дублировать сообщение тому, кто его отправил.

Параметры:

  • eventName (String) — имя события.
  • data (Any) — данные.

Пример:

socket.on('chat message', (msg) => {
    // Отправляем всем, кроме отправителя
    socket.broadcast.emit('chat message', msg);
});

5. socket.join(roomName)

Что делает: Позволяет клиенту "войти" в определенную комнату. Комнаты — это логические группы, которым можно отправлять сообщения, не затрагивая остальных. Например, можно создать комнаты для разных игровых сессий или чатов.

Параметры:

  • roomName (String) — название комнаты.

Пример:

socket.on('join room', (room) => {
    socket.join(room);
    console.log(`Клиент ${socket.id} присоединился к комнате ${room}`);
    // Отправляем сообщение только участникам этой комнаты
    io.to(room).emit('room message', `Новый участник в комнате ${room}`);
});

6. io.to(roomName).emit(eventName, data)

Что делает: Отправляет сообщение всем клиентам, которые находятся в указанной комнате. Это основная функция для работы с комнатами.

Параметры:

  • roomName (String) — название комнаты.
  • eventName (String) — имя события.
  • data (Any) — данные.

Пример:

// Отправляем сообщение всем в комнате 'game-123'
io.to('game-123').emit('game update', { score: 10, player: 'Alice' });

7. socket.on(eventName, callback)

Что делает: Подписывается на входящее событие от конкретного клиента. Это основной способ получения данных от клиента на сервере.

Параметры:

  • eventName (String) — имя события, которое отправляет клиент.
  • callback(data) — функция, которая выполняется при получении события. Принимает данные, отправленные клиентом.

Пример:

socket.on('user message', (messageData) => {
    console.log(`Получено сообщение от ${messageData.user}: ${messageData.text}`);
});

8. socket.disconnect(close)

Что делает: Принудительно отключает клиента от сервера. Вызывается со стороны сервера.

Параметры:

  • close (Boolean, опционально) — если true, закрывает транспортное соединение (например, WebSocket). По умолчанию false.

Пример:

// Отключаем клиента, если он нарушил правила
socket.on('bad behavior', () => {
    socket.disconnect(true);
});

Клиентские

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