> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# LaserStream WebSocket: потоковая передача данных Solana в реальном времени

> Передавайте данные Solana в реальном времени через LaserStream WebSocket — стандартные подписки Solana и расширения Helius, такие как transactionSubscribe, с задержкой до 200 мс меньше.

## Что такое LaserStream WebSocket?

LaserStream WebSocket — это вариант [LaserStream](/docs/ru/laserstream), использующий протокол WebSocket. Он поддерживает стандартные методы подписки Solana JSON-RPC (`accountSubscribe`, `programSubscribe`, `logsSubscribe`, `signatureSubscribe`, `slotSubscribe`, …), а также специальные расширения Helius, такие как [`transactionSubscribe`](/docs/ru/rpc/websocket/transaction-subscribe), для расширенной фильтрации. Все они доступны через единую конечную точку `wss://mainnet.helius-rpc.com` и используют ту же серверную инфраструктуру LaserStream, что и [продукт gRPC](/docs/ru/laserstream).

WebSocket обеспечивает постоянное подключение в реальном времени: вместо повторяющихся запросов «что-нибудь изменилось?» блокчейн уведомляет вас сразу после возникновения события.

<CardGroup cols={2}>
  <Card title="Real-Time Updates" icon="bolt">
    Мгновенно получайте уведомления об изменениях аккаунтов Solana, выполнении транзакций и создании новых блоков
  </Card>

  <Card title="Efficient Resource Usage" icon="leaf">
    Одно постоянное подключение вместо сотен опрашивающих HTTP-запросов
  </Card>

  <Card title="Low Latency" icon="clock">
    Задержка до 200 мс меньше, чем у стандартных WebSocket на базе Agave RPC, благодаря LaserStream
  </Card>

  <Card title="Helius Extensions" icon="filter">
    `transactionSubscribe` и расширенный `accountSubscribe` для дополнительной фильтрации поверх стандартных методов Solana
  </Card>
</CardGroup>

## Конечные точки

WebSocket — как стандартные методы Solana, так и специальные расширения Helius — доступны через единую конечную точку для каждой сети:

**Основная сеть:** `wss://mainnet.helius-rpc.com/?api-key=<API_KEY>`
**Тестовая сеть:** `wss://devnet.helius-rpc.com/?api-key=<API_KEY>`

### Gatekeeper (бета-версия)

Чтобы протестировать наш самый быстрый вариант WebSocket, используйте новую конечную точку Gatekeeper (бета-версия):

`wss://beta.helius-rpc.com/?api-key=<API_KEY>`

## Тарификация и учет использования

Использование WebSocket тарифицируется из расчета **2 кредита за 0,1 МБ** переданных несжатых данных. Открытие подключения стоит **1 кредит**.

Для высоконагруженных систем на тарифах Professional доступны [**дополнительные пакеты данных**](/docs/ru/billing/plans#дополнения-для-данных) с ежемесячным объемом данных от 5 до 100 ТБ по предсказуемой цене. Дополнительные пакеты данных можно использовать с LaserStream и WebSocket.

<Note>
  Специальные методы Helius `transactionSubscribe` и `accountSubscribe` (с фильтрами Helius) требуют [тарифа](/docs/ru/billing/plans) **Developer**, **Business** или **Professional**. Стандартные методы Solana, такие как `programSubscribe`, `logsSubscribe` и `signatureSubscribe`, доступны на всех тарифах.
</Note>

## Основные понятия

### Типы подписок

<AccordionGroup>
  <Accordion title="Account Subscriptions" icon="user">
    Отслеживайте изменения определенных аккаунтов, например балансов кошельков, аккаунтов токенов или данных программ.

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

    * Отслеживание баланса кошелька
    * Мониторинг аккаунтов токенов
    * Изменения состояния смарт-контрактов
    * Обновления сведений о владении NFT
  </Accordion>

  <Accordion title="Program Subscriptions" icon="code">
    Отслеживайте любые изменения во всех аккаунтах, принадлежащих определенной программе.

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

    * Мониторинг сделок на DEX
    * Отслеживание протоколов DeFi
    * Отслеживание активности на маркетплейсах NFT
    * Изменения игровых активов
  </Accordion>

  <Accordion title="Transaction Subscriptions" icon="receipt">
    Получайте уведомления о подтверждении определенных транзакций или о транзакциях, в которых упоминаются конкретные аккаунты.

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

    * Подтверждение платежей
    * Отслеживание статуса транзакций
    * Подтверждения с несколькими подписями
    * Мониторинг выполнения контрактов
  </Accordion>

  <Accordion title="Slot Subscriptions" icon="clock">
    Отслеживайте развитие блокчейна и окончательность на уровне слотов.

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

    * Приложения для просмотра блокчейна
    * Мониторинг состояния сети
    * Отслеживание консенсуса
    * Анализ производительности
  </Accordion>
</AccordionGroup>

### Уровни подтверждения

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

<Tabs>
  <Tab title="Processed">
    **Самый быстрый** — транзакция обработана валидатором, но не подтверждена

    * Задержка: \~400 мс
    * Риск: транзакция может быть отклонена или переупорядочена
    * Используйте для: обновления интерфейса в реальном времени (с осторожностью)
  </Tab>

  <Tab title="Confirmed">
    **Сбалансированный** — большинство участников кластера проголосовало за слот

    * Задержка: \~2–3 секунды
    * Риск: низкая вероятность отклонения
    * Используйте для: большинства приложений
  </Tab>

  <Tab title="Finalized">
    **Самый безопасный** — квалифицированное большинство участников кластера проголосовало за слот

    * Задержка: \~15–30 секунд
    * Риск: крайне низкая вероятность отклонения
    * Используйте для: финансовых приложений и транзакций на крупные суммы
  </Tab>
</Tabs>

<Info>
  **Хотите узнать больше об уровнях подтверждения?** Прочитайте нашу подробную статью в блоге: [Уровни подтверждения Solana](https://www.helius.dev/blog/solana-commitment-levels)
</Info>

## Доступные методы WebSocket

Helius поддерживает полный набор методов подписки Solana WebSocket, а также специальные расширения Helius. Все методы используют одну конечную точку `wss://mainnet.helius-rpc.com`.

### Расширения Helius

Два метода предоставляют более гибкую фильтрацию, чем стандарт Solana:

* [`transactionSubscribe`](/docs/ru/rpc/websocket/transaction-subscribe) — подписка на транзакции с учетом списков включаемых, исключаемых и обязательных аккаунтов, флагов голосования и ошибок, а также определенной подписи
* [`accountSubscribe`](/docs/ru/rpc/websocket/account-subscribe) — Helius добавляет расширенные фильтры к стандартной структуре `accountSubscribe`

### Стандартные методы Solana

`accountSubscribe`, `blockSubscribe`, `logsSubscribe`, `programSubscribe`, `rootSubscribe`, `signatureSubscribe`, `slotSubscribe`, `slotsUpdatesSubscribe`, `voteSubscribe` и соответствующие им пары `*Unsubscribe`.

<Card title="Complete API Reference" icon="book" href="/docs/ru/api-reference/rpc/websocket-methods">
  **Изучите все 18+ методов WebSocket**. Для каждого метода приведены подробные параметры, форматы ответов и примеры.
</Card>

## Как реализовать логику повторного подключения

Подключения WebSocket могут разрываться по разным причинам: из-за проблем с сетью, технического обслуживания сервера или временных сбоев. В рабочих приложениях **обязательно** реализуйте логику повторного подключения, чтобы обеспечить надежность.

### Причины разрывов подключения

<AccordionGroup>
  <Accordion title="Network Issues">
    * Проблемы с подключением к интернету
    * Переключение между сетями Wi-Fi на мобильных устройствах
    * Истечение времени ожидания корпоративного межсетевого экрана
    * Изменения маршрутизации у интернет-провайдера
  </Accordion>

  <Accordion title="Server-Side Events">
    * Плановые периоды технического обслуживания
    * Перезапуск балансировщиков нагрузки
    * Обновления узлов RPC
    * Временная защита от перегрузки
  </Accordion>

  <Accordion title="Client-Side Issues">
    * Перевод вкладки браузера в фоновый режим
    * Приостановка мобильного приложения
    * Переход компьютера в спящий режим или режим гибернации
    * Сбои или перезапуски процесса
  </Accordion>
</AccordionGroup>

### Обнаружение разрывов подключения

<Tabs>
  <Tab title="JavaScript/Browser">
    ```javascript [expandable] theme={"system"}
    class ConnectionMonitor {
      constructor(ws) {
        this.ws = ws;
        this.pingInterval = null;
        this.lastPong = Date.now();
        this.isConnected = false;
        
        this.setupEventListeners();
        this.startPingMonitoring();
      }
      
      setupEventListeners() {
        this.ws.onopen = () => {
          console.log('Connected');
          this.isConnected = true;
          this.lastPong = Date.now();
        };
        
        this.ws.onclose = (event) => {
          console.log('Disconnected:', event.code, event.reason);
          this.isConnected = false;
          this.stopPingMonitoring();
        };
        
        this.ws.onerror = (error) => {
          console.error('WebSocket error:', error);
          this.isConnected = false;
        };
        
        // Listen for pong responses (server acknowledgment)
        this.ws.onmessage = (event) => {
          const data = JSON.parse(event.data);
          if (data.method === 'pong') {
            this.lastPong = Date.now();
          }
          // Handle other messages...
        };
      }
      
      startPingMonitoring() {
        this.pingInterval = setInterval(() => {
          if (this.isConnected) {
            // Send ping to check connection health
            this.ws.send(JSON.stringify({
              jsonrpc: '2.0',
              method: 'ping',
              id: Date.now()
            }));
            
            // Check if we received a pong recently
            const timeSinceLastPong = Date.now() - this.lastPong;
            if (timeSinceLastPong > 30000) { // 30 seconds timeout
              console.warn('No pong received, connection may be stale');
              this.ws.close();
            }
          }
        }, 10000); // Ping every 10 seconds
      }
      
      stopPingMonitoring() {
        if (this.pingInterval) {
          clearInterval(this.pingInterval);
          this.pingInterval = null;
        }
      }
    }
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript [expandable] theme={"system"}
    const WebSocket = require('ws');

    class NodeConnectionMonitor {
      constructor(url) {
        this.url = url;
        this.ws = null;
        this.pingInterval = null;
        this.isAlive = false;
      }
      
      connect() {
        this.ws = new WebSocket(this.url);
        
        this.ws.on('open', () => {
          console.log('Connected');
          this.isAlive = true;
          this.startHeartbeat();
        });
        
        this.ws.on('close', () => {
          console.log('Disconnected');
          this.isAlive = false;
          this.stopHeartbeat();
        });
        
        this.ws.on('error', (error) => {
          console.error('WebSocket error:', error);
          this.isAlive = false;
        });
        
        // Built-in ping/pong handling
        this.ws.on('pong', () => {
          this.isAlive = true;
        });
      }
      
      startHeartbeat() {
        this.pingInterval = setInterval(() => {
          if (!this.isAlive) {
            console.log('Connection lost, terminating');
            return this.ws.terminate();
          }
          
          this.isAlive = false;
          this.ws.ping();
        }, 30000); // Ping every 30 seconds
      }
      
      stopHeartbeat() {
        if (this.pingInterval) {
          clearInterval(this.pingInterval);
          this.pingInterval = null;
        }
      }
    }
    ```
  </Tab>
</Tabs>

### Стратегии повторного подключения

<Tabs>
  <Tab title="Exponential Backoff">
    ```javascript [expandable] theme={"system"}
    class ExponentialBackoffReconnector {
      constructor(url, maxRetries = 10) {
        this.url = url;
        this.maxRetries = maxRetries;
        this.retryCount = 0;
        this.baseDelay = 1000; // Start with 1 second
        this.maxDelay = 30000; // Cap at 30 seconds
        this.ws = null;
        this.subscriptions = new Map();
        this.isReconnecting = false;
      }
      
      connect() {
        if (this.isReconnecting) return;
        
        try {
          this.ws = new WebSocket(this.url);
          this.setupEventHandlers();
        } catch (error) {
          console.error('Failed to create WebSocket:', error);
          this.scheduleReconnect();
        }
      }
      
      setupEventHandlers() {
        this.ws.onopen = () => {
          console.log('Connected successfully');
          this.retryCount = 0; // Reset retry count on successful connection
          this.isReconnecting = false;
          this.resubscribeAll(); // Restore subscriptions
        };
        
        this.ws.onclose = (event) => {
          console.log('Connection closed:', event.code);
          if (!this.isReconnecting) {
            this.scheduleReconnect();
          }
        };
        
        this.ws.onerror = (error) => {
          console.error('WebSocket error:', error);
        };
      }
      
      scheduleReconnect() {
        if (this.retryCount >= this.maxRetries) {
          console.error('Max retry attempts reached. Giving up.');
          return;
        }
        
        this.isReconnecting = true;
        this.retryCount++;
        
        // Calculate delay with exponential backoff + jitter
        const delay = Math.min(
          this.baseDelay * Math.pow(2, this.retryCount - 1),
          this.maxDelay
        );
        
        // Add jitter to prevent thundering herd
        const jitteredDelay = delay + (Math.random() * 1000);
        
        console.log(`Reconnecting in ${jitteredDelay}ms (attempt ${this.retryCount}/${this.maxRetries})`);
        
        setTimeout(() => {
          this.connect();
        }, jitteredDelay);
      }
      
      subscribe(method, params, callback) {
        const id = this.generateId();
        this.subscriptions.set(id, { method, params, callback });
        
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
          this.sendSubscription(id, method, params);
        }
        
        return id;
      }
      
      resubscribeAll() {
        console.log(`Restoring ${this.subscriptions.size} subscriptions`);
        for (const [id, sub] of this.subscriptions) {
          this.sendSubscription(id, sub.method, sub.params);
        }
      }
      
      sendSubscription(id, method, params) {
        this.ws.send(JSON.stringify({
          jsonrpc: '2.0',
          id: id,
          method: method,
          params: params
        }));
      }
      
      generateId() {
        return Date.now() + Math.random();
      }
    }
    ```
  </Tab>

  <Tab title="Circuit Breaker Pattern">
    ```javascript [expandable] theme={"system"}
    class CircuitBreakerWebSocket {
      constructor(url, options = {}) {
        this.url = url;
        this.failureThreshold = options.failureThreshold || 5;
        this.recoveryTimeout = options.recoveryTimeout || 60000;
        this.checkInterval = options.checkInterval || 10000;
        
        this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
        this.failureCount = 0;
        this.lastFailureTime = null;
        this.ws = null;
        this.subscriptions = new Map();
      }
      
      connect() {
        if (this.state === 'OPEN') {
          if (Date.now() - this.lastFailureTime > this.recoveryTimeout) {
            console.log('Circuit breaker moving to HALF_OPEN state');
            this.state = 'HALF_OPEN';
          } else {
            console.log('Circuit breaker is OPEN, connection blocked');
            return false;
          }
        }
        
        try {
          this.ws = new WebSocket(this.url);
          this.setupEventHandlers();
          return true;
        } catch (error) {
          this.recordFailure();
          return false;
        }
      }
      
      setupEventHandlers() {
        this.ws.onopen = () => {
          console.log('Connected - Circuit breaker CLOSED');
          this.state = 'CLOSED';
          this.failureCount = 0;
          this.resubscribeAll();
        };
        
        this.ws.onclose = () => {
          this.recordFailure();
        };
        
        this.ws.onerror = (error) => {
          console.error('WebSocket error:', error);
          this.recordFailure();
        };
      }
      
      recordFailure() {
        this.failureCount++;
        this.lastFailureTime = Date.now();
        
        console.log(`Failure recorded: ${this.failureCount}/${this.failureThreshold}`);
        
        if (this.failureCount >= this.failureThreshold) {
          console.log('Circuit breaker opened due to repeated failures');
          this.state = 'OPEN';
        }
      }
      
      startHealthCheck() {
        setInterval(() => {
          if (this.state === 'OPEN' || 
              (this.ws && this.ws.readyState !== WebSocket.OPEN)) {
            this.connect();
          }
        }, this.checkInterval);
      }
    }
    ```
  </Tab>
</Tabs>

### Тестирование логики повторного подключения

<Tabs>
  <Tab title="Network Simulation">
    ```javascript [expandable] theme={"system"}
    // Test disconnection scenarios
    class NetworkSimulator {
      constructor(wsManager) {
        this.wsManager = wsManager;
      }
      
      // Simulate network outage
      simulateNetworkOutage(duration = 5000) {
        console.log('Simulating network outage...');
        
        // Force close the connection
        if (this.wsManager.ws) {
          this.wsManager.ws.close(1006, 'Network outage simulation');
        }
        
        // Block reconnection temporarily
        const originalConnect = this.wsManager.connect.bind(this.wsManager);
        this.wsManager.connect = () => {
          console.log('Connection blocked during outage simulation');
        };
        
        // Restore connection after duration
        setTimeout(() => {
          console.log('Network restored');
          this.wsManager.connect = originalConnect;
          this.wsManager.connect();
        }, duration);
      }
      
      // Simulate intermittent connectivity
      simulateIntermittentConnectivity() {
        setInterval(() => {
          if (Math.random() < 0.1) { // 10% chance every 10 seconds
            console.log('Simulating connection drop...');
            this.wsManager.ws?.close(1006, 'Intermittent connectivity');
          }
        }, 10000);
      }
    }

    // Usage
    const simulator = new NetworkSimulator(wsManager);
    simulator.simulateNetworkOutage(10000); // 10 second outage
    ```
  </Tab>

  <Tab title="Automated Testing">
    ```javascript [expandable] theme={"system"}
    // Jest test example
    describe('WebSocket Reconnection', () => {
      let wsManager;
      
      beforeEach(() => {
        wsManager = new ProductionWebSocketManager({
          endpoint: 'ws://localhost:8080',
          apiKey: 'test-key'
        });
      });
      
      test('should reconnect after connection loss', async () => {
        const reconnectPromise = new Promise((resolve) => {
          wsManager.on('connected', resolve);
        });
        
        await wsManager.connect();
        
        // Simulate connection loss
        wsManager.ws.close(1006, 'Test disconnection');
        
        // Wait for reconnection
        await reconnectPromise;
        
        expect(wsManager.connectionState).toBe('CONNECTED');
        expect(wsManager.metrics.reconnections).toBeGreaterThan(0);
      });
      
      test('should restore subscriptions after reconnection', async () => {
        await wsManager.connect();
        
        const messages = [];
        const subscriptionId = wsManager.subscribe(
          'accountSubscribe',
          ['test-account', {}],
          (data) => messages.push(data)
        );
        
        // Verify subscription exists
        expect(wsManager.subscriptions.has(subscriptionId)).toBe(true);
        
        // Simulate disconnection and reconnection
        wsManager.ws.close(1006, 'Test disconnection');
        
        await new Promise(resolve => wsManager.on('connected', resolve));
        
        // Verify subscription was restored
        const subscription = wsManager.subscriptions.get(subscriptionId);
        expect(subscription.pending).toBe(true); // Should be re-subscribing
      });
    });
    ```
  </Tab>
</Tabs>

<Warning>
  **Критически важно для рабочей среды**: корректная логика повторного подключения обязательна для рабочих приложений. Подключения WebSocket будут разрываться — учитывайте это при проектировании, тестируйте логику и отслеживайте ее работу в рабочей среде.
</Warning>

## Устранение неполадок

<AccordionGroup>
  <Accordion title="Connection Failed">
    **Признаки**: не удается установить первоначальное подключение WebSocket

    **Решения**:

    * Убедитесь, что ваш ключ API указан правильно и на балансе достаточно кредитов
    * Проверьте формат URL конечной точки: `wss://mainnet.helius-rpc.com?api-key=YOUR_KEY`
    * Убедитесь, что межсетевой экран разрешает подключения WebSocket через порт 443
    * Сначала отправьте простой ping-запрос, чтобы проверить базовое подключение
  </Accordion>

  <Accordion title="Frequent Disconnections">
    **Признаки**: подключение разрывается каждые несколько минут

    **Решения**:

    * Для WebSocket действует **10-минутный таймер бездействия**. Отправляйте ping-запрос не реже одного раза в минуту, чтобы сохранять подключение активным (см. примеры повторного подключения выше и [часто задаваемые вопросы о WebSocket](/docs/ru/faqs/websockets#отключения-и-повторные-подключения))
    * Реализуйте корректную проверку активности с помощью ping/pong (показана в примерах повторного подключения выше)
    * Проверьте стабильность сети и настройки корпоративного межсетевого экрана
    * Следите за количеством подписок: слишком большое их число может привести к нестабильности
    * Убедитесь, что правильно обрабатываете жизненный цикл подключения
  </Accordion>

  <Accordion title="Missing Messages">
    **Признаки**: ожидаемые обновления подписки не поступают

    **Решения**:

    * Убедитесь, что подписка подтверждена (проверьте ответ)
    * Убедитесь, что в отслеживаемом аккаунте или программе действительно есть активность
    * Следите за состоянием подключения: пропущенные сообщения часто указывают на разрывы
  </Accordion>

  <Accordion title="High Latency">
    **Признаки**: медленная доставка сообщений и задержки обновлений

    **Решения**:

    * Используйте уровень подтверждения «confirmed» вместо «finalized»
    * Уменьшите количество активных подписок
    * Оптимизируйте логику обработки сообщений
    * Рассмотрите возможность распределения нагрузки между несколькими подключениями
    * Проверьте качество сетевого подключения
  </Accordion>

  <Accordion title="Memory Leaks">
    **Признаки**: объем используемой приложением памяти со временем увеличивается

    **Решения**:

    * Реализуйте корректную очистку подписок
    * Удаляйте обработчики событий при размонтировании компонентов
    * Периодически очищайте журналы сообщений
    * Отслеживайте количество подписок и применяйте ограничения
    * По возможности используйте слабые ссылки для функций обратного вызова
  </Accordion>
</AccordionGroup>

## Переход со стандартного RPC

Если вы сейчас используете опрос через HTTP, перейдите на WebSocket следующим образом:

```javascript [expandable] theme={"system"}
// Old approach - HTTP polling
class HTTPAccountMonitor {
  constructor(connection, accountAddress) {
    this.connection = connection;
    this.accountAddress = accountAddress;
    this.interval = null;
    this.lastKnownBalance = null;
  }

  start() {
    this.interval = setInterval(async () => {
      try {
        const accountInfo = await this.connection.getAccountInfo(
          new PublicKey(this.accountAddress)
        );
        
        const currentBalance = accountInfo?.lamports || 0;
        
        if (this.lastKnownBalance !== currentBalance) {
          console.log(`Balance changed: ${currentBalance}`);
          this.lastKnownBalance = currentBalance;
        }
      } catch (error) {
        console.error('Failed to fetch account info:', error);
      }
    }, 2000); // Poll every 2 seconds
  }

  stop() {
    if (this.interval) {
      clearInterval(this.interval);
      this.interval = null;
    }
  }
}

// New approach - WebSocket subscription
class WebSocketAccountMonitor {
  constructor(wsManager, accountAddress) {
    this.wsManager = wsManager;
    this.accountAddress = accountAddress;
    this.subscriptionId = null;
  }

  start() {
    this.subscriptionId = this.wsManager.subscribe(
      'accountSubscribe',
      [
        this.accountAddress,
        { encoding: 'jsonParsed', commitment: 'confirmed' }
      ],
      (data) => {
        const currentBalance = data.value.lamports;
        console.log(`Balance changed: ${currentBalance}`);
        
        // Handle the change immediately - no polling delay!
      }
    );
  }

  stop() {
    if (this.subscriptionId) {
      this.wsManager.unsubscribe(this.subscriptionId);
      this.subscriptionId = null;
    }
  }
}
```

## Расширенные возможности

Если вашему приложению нужны еще более продвинутые возможности, рассмотрите [LaserStream gRPC](/docs/ru/laserstream):

<CardGroup cols={2}>
  <Card title="24-Hour Historical Replay" icon="clock-rotate-left">
    Получайте пропущенные данные после периода, когда приложение было отключено
  </Card>

  <Card title="Multi-Node Aggregation" icon="network-wired">
    Повышайте надежность за счет данных от нескольких валидаторов
  </Card>

  <Card title="Higher Throughput" icon="gauge-high">
    Обрабатывайте больше подписок и повышенный поток сообщений
  </Card>

  <Card title="Enterprise Features" icon="building">
    Расширенный мониторинг, аналитика и конвейеры обработки данных
  </Card>
</CardGroup>

## Начало работы

Готовы начать?

Практические примеры и пошаговые инструкции по реализации приведены в нашем [руководстве по быстрому запуску WebSocket](/docs/ru/rpc/websocket/quickstart).

## Руководства

Пошаговые руководства с готовым к запуску кодом доступны на странице [руководств по LaserStream WebSocket](/docs/ru/rpc/websocket/guides).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.