Spec-Zone.ru › Socket.IO 4

Введение

Что такое Socket.IO

Socket.IO — это библиотека, которая позволяет осуществлять низкозадержное, двустороннее и событийно-ориентированное общение между клиентом и сервером.

Diagram of a communication between a server and a client

Она построена на основе протокола WebSocket и предоставляет дополнительные гарантии, такие как откат к HTTP long-polling или автоматическое переподключение.

WebSocket — это протокол связи, который обеспечивает полнодуплексный и низкозадержный канал между сервером и браузером. Дополнительную информацию можно найти здесь.

Доступны несколько реализаций сервера Socket.IO:

  • JavaScript (Node.js) (документация по которому находится на этом сайте)
    • Шаги установки
    • API
    • Исходный код
  • JavaScript (Deno): https://github.com/socketio/socket.io-deno
  • Java: https://github.com/mrniko/netty-socketio
  • Java: https://github.com/trinopoty/socket.io-server-java
  • Python: https://github.com/miguelgrinberg/python-socketio
  • Golang: https://github.com/googollee/go-socket.io

И реализации клиента на большинстве основных языков:

  • JavaScript (который можно запустить как в браузере, так и в Node.js или React Native)
    • Шаги установки
    • API
    • Исходный код
  • Java: https://github.com/socketio/socket.io-client-java
  • C++: https://github.com/socketio/socket.io-client-cpp
  • Swift: https://github.com/socketio/socket.io-client-swift
  • Dart: https://github.com/rikulo/socket.io-client-dart
  • Python: https://github.com/miguelgrinberg/python-socketio
  • .Net: https://github.com/doghappy/socket.io-client-csharp
  • Rust: https://github.com/1c3t3a/rust-socketio
  • Kotlin: https://github.com/icerockdev/moko-socket-io

Вот базовый пример с обычными WebSockets:

Сервер (на основе ws)

import { WebSocketServer } from "ws";

const server = new WebSocketServer({ port: 3000 });

server.on("connection", (socket) => {
  // send a message to the client
  socket.send(JSON.stringify({
    type: "hello from server",
    content: [ 1, "2" ]
  }));

  // receive a message from the client
  socket.on("message", (data) => {
    const packet = JSON.parse(data);

    switch (packet.type) {
      case "hello from client":
        // ...
        break;
    }
  });
});

Клиент

const socket = new WebSocket("ws://localhost:3000");

socket.addEventListener("open", () => {
  // send a message to the server
  socket.send(JSON.stringify({
    type: "hello from client",
    content: [ 3, "4" ]
  }));
});

// receive a message from the server
socket.addEventListener("message", ({ data }) => {
  const packet = JSON.parse(data);

  switch (packet.type) {
    case "hello from server":
      // ...
      break;
  }
});

И вот тот же пример с Socket.IO:

Сервер

import { Server } from "socket.io";

const io = new Server(3000);

io.on("connection", (socket) => {
  // send a message to the client
  socket.emit("hello from server", 1, "2", { 3: Buffer.from([4]) });

  // receive a message from the client
  socket.on("hello from client", (...args) => {
    // ...
  });
});

Клиент

import { io } from "socket.io-client";

const socket = io("ws://localhost:3000");

// send a message to the server
socket.emit("hello from client", 5, "6", { 7: Uint8Array.from([8]) });

// receive a message from the server
socket.on("hello from server", (...args) => {
  // ...
});

Оба примера выглядят очень похожими, но под капотом Socket.IO предоставляет дополнительные функции, которые скрывают сложность работы приложения на основе WebSockets в производстве. Эти функции перечислены ниже.

Но сначала давайте разберёмся, чем Socket.IO не является.

Что Socket.IO не является

Socket.IO — это НЕ реализация WebSocket.

Хотя Socket.IO действительно использует WebSocket для передачи данных, когда это возможно, она добавляет дополнительную метаданные к каждому пакету. Именно поэтому клиент WebSocket не сможет успешно подключиться к серверу Socket.IO, а клиент Socket.IO не сможет подключиться к простому серверу WebSocket.

// WARNING: the client will NOT be able to connect!
const socket = io("ws://echo.websocket.org");

Если вам нужен обычный сервер WebSocket, обратите внимание на ws или µWebSockets.js.

Также есть обсуждения о включении сервера WebSocket в ядро Node.js.

Со стороны клиента вы можете быть заинтересованы в пакете robust-websocket.

Socket.IO не предназначен для использования в фоновом сервисе мобильных приложений.

Библиотека Socket.IO поддерживает открытое TCP-соединение с сервером, что может привести к высокому расходу заряда батареи у ваших пользователей. Для этого случая используйте специализированную платформу обмена сообщениями, например, FCM.

Функции

Вот функции, предоставляемые Socket.IO по сравнению с обычными WebSockets:

Откат к HTTP long-polling

При невозможности установить соединение WebSocket соединение будет откатиться к HTTP long-polling.

Эта функция была основной причиной использования Socket.IO более десяти лет назад (!), поскольку поддержка WebSockets в браузерах всё ещё была на ранней стадии.

Даже если большинство браузеров сейчас поддерживают WebSockets (более чем 97%), это всё ещё отличная функция, так как мы всё ещё получаем сообщения от пользователей, которые не могут установить соединение WebSocket из-за неправильно настроенных прокси-серверов.

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

В определённых условиях соединение WebSocket между сервером и клиентом может быть прервано, и обе стороны не будут знать о разрыве соединения.

Поэтому Socket.IO включает механизм проверки состояния соединения.

И когда клиент в конечном итоге отключается, он автоматически переподключается с экспоненциальной задержкой, чтобы не перегружать сервер.

Буферизация пакетов

Пакеты автоматически буферизуются, когда клиент отключён, и будут отправлены при переподключении.

Дополнительную информацию можно найти здесь.

Подтверждения

Socket.IO предоставляет удобный способ отправки события и получения ответа:

Отправитель

socket.emit("hello", "world", (response) => {
  console.log(response); // "got it"
});

Получатель

socket.on("hello", (arg, callback) => {
  console.log(arg); // "world"
  callback("got it");
});

Вы также можете добавить таймаут:

socket.timeout(5000).emit("hello", "world", (err, response) => {
  if (err) {
    // the other side did not acknowledge the event in the given delay
  } else {
    console.log(response); // "got it"
  }
});

Вещание

На стороне сервера вы можете отправить событие всем подключённым клиентам или подмножеству клиентов:

// to all connected clients
io.emit("hello");

// to all connected clients in the "news" room
io.to("news").emit("hello");

Это также работает при масштабировании на несколько узлов.

Мультиплексирование

Пространства имён позволяют разделить логику вашего приложения на одном общем соединении. Это может быть полезно, например, если вы хотите создать канал «администратора», к которому могут присоединиться только авторизованные пользователи.

io.on("connection", (socket) => {
  // classic users
});

io.of("/admin").on("connection", (socket) => {
  // admin users
});

Подробнее об этом здесь.

Часто задаваемые вопросы

Нужен ли Socket.IO сегодня?

Это справедливый вопрос, поскольку WebSockets теперь поддерживаются почти везде.

Тем не менее, мы считаем, что если вы используете обычные WebSockets для своего приложения, вам в конечном итоге придётся реализовать большинство функций, которые уже включены (и проверены временем) в Socket.IO, такие как переподключение, подтверждения или вещание.

Какова нагрузка протокола Socket.IO?

socket.emit("hello", "world") будет отправлен как один кадр WebSocket, содержащий 42["hello","world"] с:

  • 4 — тип пакета Engine.IO «сообщение»
  • 2 — тип пакета Socket.IO «сообщение»
  • ["hello","world"] — JSON.stringify()-версия массива аргументов

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

Размер самого пакета браузера составляет 10.4 kB (минифицированный и сжатый).

Что-то работает неправильно, нужна помощь?

Пожалуйста, ознакомьтесь с руководством по устранению неполадок.

Следующие шаги

  • Пример начала работы
  • Установка сервера
  • Установка клиента

© 2014–2021 Automattic
Licensed under the MIT License.
https://socket.io/docs/v4

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API