> ## 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.

# Обработка переподключений и ошибок в разобранных потоках

> Обнаруживайте разрывы соединения с разобранными потоками, переподключайтесь с задержкой, возобновляйте подписки и восполняйте данные точно за пропущенный диапазон слотов.

Доставка выполняется **не более одного раза** — повторного воспроизведения нет. Данные, подтверждённые во время отсутствия соединения, не отправляются повторно, поэтому рабочий клиент должен обнаружить пропуск и решить, нужно ли его восполнить. Для этого используется `context.slot`: он определяет границы диапазона, пропущенного во время разрыва соединения. В этом руководстве объясняется, почему соединения закрываются, как корректно переподключаться и как использовать этот диапазон.

## Почему соединения закрываются

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

| Код | Причина | Что делать |
| - | - | - |
| 1000 | Простой: в течение 10 минут нет сообщений от клиента и уведомлений | Переподключитесь и возобновите подписки. Пинги уровня протокола WebSocket, которые клиентские библиотеки отправляют автоматически, **не** сбрасывают таймер простоя. |
| 1001 | Перезапуск сервера (развёртывание) | Переподключитесь и возобновите подписки |
| 1008 | Медленный потребитель: отставание превысило 2048 уведомлений | Переподключитесь с более узким фильтром, `details: "matched"` или `"raw"`, либо ускорьте обработку |
| 1005 / 1006 | Сетевой узел повторно создал соединение | Переподключитесь и возобновите подписки; это нормально с определённой периодичностью для любого долгоживущего соединения |

Сервер отправляет пинг каждые 15 секунд, поэтому даже исправное, но неактивное соединение продолжает передавать трафик. Если более минуты нет вообще никаких данных — ни уведомлений, ни пингов, — считайте соединение разорванным и переподключитесь, не дожидаясь сигнала от сокета.

## Узкие фильтры и тайм-аут простоя

Если фильтр настолько узкий, что совпадений обоснованно может не быть в течение 10 минут, ожидайте, что сервер закроет соединение с кодом 1000. Обрабатывайте это как любое другое закрытие: переподключитесь, возобновите подписки и восполните пропуск, как описано ниже.

## Переподключение и обнаружение пропуска

<Steps>
  <Step title="Reconnect with Backoff">
    При любом закрытии — ожидаемом или нет — переподключайтесь с экспоненциальной задержкой. Идентификаторы подписок не сохраняются после переподключения, поэтому повторно отправьте `parsedTransactionSubscribe` для каждого ранее открытого фильтра.
  </Step>

  <Step title="Track context.slot Across Disconnects">
    Сохраните последнее значение `context.slot`, полученное перед разрывом соединения. Промежуток между этим слотом и первым слотом, полученным после переподключения, точно соответствует пропущенному диапазону — не больше и не меньше.
  </Step>

  <Step title="Backfill if You Need To">
    Если приложение не допускает пропусков, восполните данные за этот диапазон слотов через RPC: используйте `getSignaturesForAddress`, чтобы перечислить транзакции в диапазоне, а затем `getTransaction`, чтобы получить каждую из них. Это ручной этап сверки — сами разобранные потоки не воспроизводят данные повторно.
  </Step>
</Steps>

```typescript theme={"system"}
import WebSocket from "ws";

const URL = "wss://beta.helius-rpc.com/?api-key=<API_KEY>";
const filters = [
  { programs: ["JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"] },
];

let lastSlotSeen: number | null = null;
let backoffMs = 1000;

function connect() {
  const ws = new WebSocket(URL);

  ws.on("open", () => {
    backoffMs = 1000;
    filters.forEach((filter, i) => {
      ws.send(JSON.stringify({
        jsonrpc: "2.0",
        id: i + 1,
        method: "parsedTransactionSubscribe",
        params: [filter],
      }));
    });
  });

  ws.on("message", (data) => {
    const msg = JSON.parse(data.toString());
    if (msg.method === "parsedTransactionNotification") {
      const { slot } = msg.params.result.context;

      // Across reconnects, the slot bounds the backfill window.
      if (lastSlotSeen !== null && slot > lastSlotSeen) {
        // backfill candidates: slots lastSlotSeen+1 .. slot-1 while disconnected
      }
      lastSlotSeen = slot;
    }
  });

  ws.on("close", (code) => {
    console.warn(`connection closed (${code}); reconnecting in ${backoffMs}ms`);
    setTimeout(connect, backoffMs);
    backoffMs = Math.min(backoffMs * 2, 30_000);
  });
}

connect();
```

Значение `context.slot` сохраняет актуальность после переподключения: отслеживайте наибольший слот, полностью обработанный до разрыва соединения, и считайте всё после него диапазоном для восполнения данных.

## Обработка ошибок JSON-RPC

Неудачные запросы возвращают ошибку JSON-RPC вместо результата, поэтому логику обработки можно ветвить по `error.code`:

| Код | Значение |
| - | - |
| `-32700` | Ошибка разбора (недопустимый JSON) |
| `-32600` | Недопустимый запрос |
| `-32601` | Метод не найден |
| `-32602` | Недопустимые параметры: неверный открытый ключ, неизвестное поле, неподдерживаемое значение уровня подтверждения или детализации |
| `-32000` | Превышен лимит фильтров |
| `-32001` | Сервер не готов; повторите попытку с задержкой |
| `-32002` | Превышено ограничение частоты запросов (10 сообщений в секунду) |
| `-32006` | Слишком много подписок (25 на одно соединение) |

Ошибки `-32602` и `-32000` означают, что сам запрос составлен неправильно: исправьте фильтр и не повторяйте запрос без изменений. Ошибки `-32001` и `-32002` временные; повторите запрос с той же задержкой, которую используете при переподключении.

## Дальнейшие действия

<CardGroup cols={2}>
  <Card title="Quickstart" icon="bolt" href="/docs/ru/parsed-streams/quickstart">
    Полное описание протокола: методы, поля фильтров и ограничения.
  </Card>

  <Card title="Track Jupiter Swaps" icon="arrow-right-arrow-left" href="/docs/ru/parsed-streams/guides/track-jupiter-swaps">
    Создайте фильтр, на который можно подписаться через это соединение.
  </Card>
</CardGroup>


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