Реализация WebTransport для low-latency коммуникации на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация WebTransport для low-latency коммуникации на сайте
Сложная
~5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация WebTransport для low-latency коммуникации на сайте

WebTransport — браузерный API поверх HTTP/3 (QUIC), доступный с Chrome 97, Edge 97, Firefox 114. В отличие от WebSocket, работает поверх UDP через QUIC, поддерживает несколько независимых потоков и датаграммы без head-of-line blocking. Для задач с требованием к задержке ниже 50 мс — это качественный шаг вперёд по сравнению с WebSocket.

Где WebTransport выигрывает у WebSocket

WebSocket — это один TCP-поток. Потеря пакета блокирует всю очередь (head-of-line blocking). При плохом соединении задержки растут непропорционально. QUIC решает это мультиплексированием: каждый поток независим, потеря пакета в одном не влияет на другие.

Характеристика WebSocket WebTransport
Протокол TCP QUIC (UDP)
Мультиплексирование Нет Да (независимые потоки)
Датаграммы (ненадёжные) Нет Да
Head-of-line blocking Есть Нет (для разных потоков)
Поддержка браузеров Все Chrome 97+, Firefox 114+, Edge 97+
0-RTT reconnect Нет Да (QUIC session resumption)

Требования к серверу

WebTransport требует HTTP/3. Варианты:

  • Go: quic-go + webtransport-go
  • Node.js: @fails-components/webtransport (экспериментальный)
  • Python: aioquic
  • Cloudflare Workers: нативная поддержка WebTransport через Workers API
  • nginx/Caddy: пока нет нативной поддержки WebTransport как прокси

Минимальный сервер на Go с webtransport-go:

package main

import (
    "context"
    "crypto/tls"
    "log"
    "net/http"

    "github.com/quic-go/quic-go/http3"
    "github.com/quic-go/webtransport-go"
)

func main() {
    s := webtransport.Server{
        H3: http3.Server{
            Addr:      ":4433",
            TLSConfig: loadTLSConfig(), // TLS обязателен
        },
    }

    http.HandleFunc("/wt", func(w http.ResponseWriter, r *http.Request) {
        session, err := s.Upgrade(w, r)
        if err != nil {
            log.Printf("upgrade error: %v", err)
            return
        }
        handleSession(session)
    })

    s.ListenAndServe()
}

func handleSession(session *webtransport.Session) {
    ctx := context.Background()
    for {
        // Принимаем входящий двунаправленный поток
        stream, err := session.AcceptStream(ctx)
        if err != nil {
            return
        }
        go handleStream(stream)
    }
}

Клиентская часть: базовое подключение

const transport = new WebTransport('https://your-server:4433/wt');

// Ждём готовности
await transport.ready;
console.log('WebTransport connected');

transport.closed.then(() => console.log('Transport closed'));

// Обработка ошибок
transport.closed.catch(err => console.error('Transport error:', err));

Двунаправленные потоки (Bidirectional Streams)

Потоки — надёжные упорядоченные каналы, аналог нескольких независимых WebSocket в одном соединении:

// Клиент открывает поток
const stream = await transport.createBidirectionalStream();
const writer = stream.writable.getWriter();
const reader = stream.readable.getReader();

// Отправка
const encoder = new TextEncoder();
await writer.write(encoder.encode(JSON.stringify({ type: 'subscribe', channel: 'prices' })));

// Чтение ответов
const decoder = new TextDecoder();
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  const message = JSON.parse(decoder.decode(value));
  handleMessage(message);
}

Сервер может инициировать потоки в сторону клиента:

// Клиент принимает входящие потоки от сервера
const streamReader = transport.incomingBidirectionalStreams.getReader();
while (true) {
  const { value: stream, done } = await streamReader.read();
  if (done) break;
  processServerStream(stream);
}

Датаграммы (Datagrams)

Ненадёжные, неупорядоченные UDP-like сообщения. Для позиций игроков, метрик, курсоров — где задержка важнее гарантии доставки:

// Отправка датаграммы
const datagramWriter = transport.datagrams.writable.getWriter();
const encoder = new TextEncoder();

function sendPosition(x, y) {
  const data = encoder.encode(JSON.stringify({ x, y, ts: Date.now() }));
  // Не ждём подтверждения, fire-and-forget
  datagramWriter.write(data).catch(() => {}); // потеря пакета — норма
}

// Получение датаграмм
const datagramReader = transport.datagrams.readable.getReader();
const decoder = new TextDecoder();

(async () => {
  while (true) {
    const { value, done } = await datagramReader.read();
    if (done) break;
    const msg = JSON.parse(decoder.decode(value));
    updateRemotePosition(msg);
  }
})();

Однонаправленные потоки

Для потоковой отправки данных (стриминг событий, лог, бинарные данные):

// Клиент -> Сервер: однонаправленный поток
const sendStream = await transport.createUnidirectionalStream();
const writer = sendStream.getWriter();
await writer.write(encodeChunk(data));
await writer.close();

// Сервер -> Клиент: входящие однонаправленные потоки
const incomingReader = transport.incomingUnidirectionalStreams.getReader();
while (true) {
  const { value: stream, done } = await incomingReader.read();
  if (done) break;
  const reader = stream.getReader();
  // читаем данные из stream
}

Реальный кейс: торговый терминал

Биржевые котировки требуют минимальной задержки. Архитектура с WebTransport:

Биржевой фид (UDP) -> Go-сервер -> WebTransport -> Браузер
  • Датаграммы для тиков цен (fire-and-forget, потеря 1–2% тиков допустима)
  • Надёжный поток для ордеров и подтверждений
  • Отдельный поток для подписок на инструменты
class MarketDataClient {
  constructor(url) {
    this.transport = null;
    this.orderStream = null;
    this.subscriptions = new Map();
  }

  async connect(url) {
    this.transport = new WebTransport(url);
    await this.transport.ready;

    // Создаём поток для ордеров (надёжный)
    this.orderStream = await this.transport.createBidirectionalStream();

    // Слушаем датаграммы (тики)
    this.listenTicks();
  }

  async listenTicks() {
    const reader = this.transport.datagrams.readable.getReader();
    while (true) {
      const { value, done } = await reader.read();
      if (done) break;
      const tick = decodeTick(value); // бинарный протобаф
      this.subscriptions.get(tick.symbol)?.(tick);
    }
  }

  async placeOrder(order) {
    const writer = this.orderStream.writable.getWriter();
    await writer.write(encodeOrder(order));
    writer.releaseLock();
    // Читаем подтверждение из того же потока
    return readOrderConfirmation(this.orderStream.readable);
  }
}

Проблема TLS-сертификата в разработке

WebTransport требует валидный TLS. В dev-среде — два варианта:

1. Chrome флаг для self-signed:

chrome://flags/#allow-insecure-localhost

2. Certificate pinning через serverCertificateHashes:

const transport = new WebTransport('https://localhost:4433/wt', {
  serverCertificateHashes: [{
    algorithm: 'sha-256',
    value: hexToArrayBuffer('YOUR_CERT_SHA256_HASH'),
  }],
});

Сертификат должен быть выдан максимум на 14 дней при использовании этого метода — генерируется скриптом при запуске dev-сервера.

Fallback стратегия

WebTransport не поддерживается Safari (по состоянию на начало 2026). Нужен graceful fallback:

async function createTransport(url) {
  if ('WebTransport' in window) {
    try {
      const wt = new WebTransport(url.replace('wss://', 'https://'));
      await wt.ready;
      return new WebTransportAdapter(wt);
    } catch (e) {
      console.warn('WebTransport failed, falling back to WebSocket');
    }
  }
  return new WebSocketAdapter(url);
}

Адаптер скрывает разницу за единым интерфейсом send(data) / on('message', cb).

Сроки

  • Прототип с датаграммами и одним потоком — 2–3 дня
  • Production-сервер на Go с TLS + комплексной обработкой потоков — 1 неделя
  • Полноценный клиент с fallback на WebSocket, мониторингом задержек, reconnect — 2–3 недели
  • Интеграция с существующим real-time приложением (замена WebSocket) — 3–5 дней при наличии адаптерного слоя