Spec-Zone.ru › Socket.IO 4

Настраиваемый парсер

С версии Socket.IO v2.0.0 теперь можно использовать собственный парсер для управления сериализацией/десериализацией пакетов.

Сервер

const httpServer = require("http").createServer();
const io = require("socket.io")(httpServer, {
  parser: myParser
});

Клиент

const socket = io({
  parser: myParser
});

Реализация собственного парсера

Вот базовый пример с парсером, использующим методы JSON.stringify() и JSON.parse().

const Emitter = require("component-emitter"); // polyfill of Node.js EventEmitter in the browser 

class Encoder {
  /**
   * Encode a packet into a list of strings/buffers
   */
  encode(packet) {
    return [JSON.stringify(packet)];
  }
}

class Decoder extends Emitter {
  /**
   * Receive a chunk (string or buffer) and optionally emit a "decoded" event with the reconstructed packet
   */
  add(chunk) {
    const packet = JSON.parse(chunk);
    if (this.isPacketValid(packet)) {
      this.emit("decoded", packet);
    } else {
      throw new Error("invalid format");
    }
  }
  isPacketValid({ type, data, nsp, id }) {
    const isNamespaceValid = typeof nsp === "string";
    const isAckIdValid = id === undefined || Number.isInteger(id);
    if (!isNamespaceValid || !isAckIdValid) {
      return false;
    }
    switch (type) {
      case 0: // CONNECT
        return data === undefined || typeof data === "object";
      case 1: // DISCONNECT
        return data === undefined;
      case 2: // EVENT
        return Array.isArray(data) && data.length > 0;
      case 3: // ACK
        return Array.isArray(data);
      case 4: // CONNECT_ERROR
        return typeof data === "object";
      default:
        return false;
    }
  }
  /**
   * Clean up internal buffers
   */
  destroy() {}
}

module.exports = { Encoder, Decoder };

Парсер по умолчанию

Исходный код парсера по умолчанию (пакет socket.io-parser) можно найти здесь: https://github.com/socketio/socket.io-parser

Пример вывода:

  • базовое отправление
socket.emit("test", 42);

будет закодировано как:

2["test",42]
||
|└─ JSON-encoded payload
└─ packet type (2 => EVENT)
  • отправка с бинарными данными, подтверждением и пользовательским пространством имен
socket.emit("test", Uint8Array.from([42]), () => {
  console.log("ack received");
});

будет закодировано как:

51-/admin,13["test",{"_placeholder":true,"num":0}]
||||     || └─ JSON-encoded payload with placeholders for binary attachments
||||     |└─ acknowledgement id
||||     └─ separator
|||└─ namespace (not included when it's the main namespace)
||└─ separator
|└─ number of binary attachments
└─ packet type (5 => BINARY EVENT)

and an additional attachment (the extracted Uint8Array)

Преимущества:

  • вложение бинарных данных затем кодируется в Base64, поэтому этот парсер совместим с браузерами, которые не поддерживают ArrayBuffers, например, IE9

Недостатки:

  • пакеты с бинарным содержимым отправляются как два отдельных кадра WebSocket (если соединение WebSocket установлено)

Парсер msgpack

Этот парсер использует формат сериализации MessagePack.

Исходный код этого парсера можно найти здесь: https://github.com/socketio/socket.io-msgpack-parser

Пример использования:

Сервер

const httpServer = require("http").createServer();
const io = require("socket.io")(httpServer, {
  parser: require("socket.io-msgpack-parser")
});

Клиент (Node.js)

const socket = require("socket.io-client")("https://example.com", {
  parser: require("socket.io-msgpack-parser")
});

В браузере теперь есть официальный пакет, который включает этот парсер:

  • https://cdn.socket.io/4.5.0/socket.io.msgpack.min.js
  • cdnjs: https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.0/socket.io.msgpack.min.js
  • jsDelivr: https://cdn.jsdelivr.net/npm/socket.io-client@4.5.0/dist/socket.io.msgpack.min.js
  • unpkg: https://unpkg.com/socket.io-client@4.5.0/dist/socket.io.msgpack.min.js

В этом случае вам не нужно указывать опцию parser.

Преимущества:

  • пакеты с бинарным содержимым отправляются как один единственный кадр WebSocket (если соединение WebSocket установлено)
  • может привести к более компактным пакетам (особенно при использовании большого количества чисел)

Недостатки:

  • несовместим с браузерами, которые не поддерживают ArrayBuffers, например, IE9
  • сложнее отладить во вкладке «Сеть» браузера

Обратите внимание, что socket.io-msgpack-parser полагается на реализацию MessagePack notepack.io. Эта реализация в основном ориентирована на производительность и минимальный размер пакета и, следовательно, не поддерживает такие функции, как типы расширений. Для парсера, основанного на официальной реализации JavaScript, пожалуйста, проверьте этот пакет.

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

Spec-Zone.ru

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