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

# パースされたストリームでの再接続とエラーの処理

> パースされたストリームの切断を検出し、バックオフで再接続し、再購読し、見逃したスロットウィンドウを正確にバックフィルします。

配信は**最大1回**です — 再送はありません。切断中に確認されたものは再送されないため、プロダクションクライアントはギャップを検出し、それをバックフィルするかどうかを決定する必要があります。そのシグナルは`context.slot`です: 切断中に見逃したウィンドウの範囲を示します。このガイドでは、なぜ接続が切れるのか、どのようにクリーンに再接続するのか、そしてそれをどのように活用するのかを説明します。

## 接続が切断される理由

すべての切断には、何が起こったか、次に何をするべきかを示すWebSocketクローズコードがあります。

| コード         | 理由                          | 対処方法                                                                                                 |
| ----------- | --------------------------- | ---------------------------------------------------------------------------------------------------- |
| 1000        | アイデル: クライアントメッセージや通知が10分間ない | フィルターが静かなら数分ごとにJSON-RPCの`ping`メソッドを送信します。クライアントライブラリが自動的に送信するプロトコルレベルのWebSocketピンはアイドルタイマーをリセットしません。 |
| 1001        | サーバーリスタート（デプロイ）             | 再接続して再購読                                                                                             |
| 1008        | スローコンシューマ: 2048通知以上遅れを取った   | より狭いフィルター、`details: "matched"` または `"raw"`、もしくは高速な処理で再接続                                             |
| 1005 / 1006 | ネットワークエッジが接続を再利用            | 再接続して再購読; 長期間接続時には正常な頻度で発生する                                                                         |

サーバーは15秒ごとにピングを行うため、健康だが静かな接続でもトラフィックが流れます。1分以上まったく何もない場合（通知もピングもない）— 接続が死んでいると仮定して再接続し、ソケットが教えてくれるのを待たないでください。

## 接続を維持する

フィルターが狭いために10分間マッチしない場合、10分未満の間隔で明示的にJSON-RPCの`ping`を送信します。

```json theme={"system"}
{ "jsonrpc": "2.0", "id": 99, "method": "ping" }
```

これは現在のスロットを返し、さらに重要なことに、アイドルタイマー用のクライアントメッセージとしてカウントされます。ライブラリレベルのWebSocketピンフレームはそうではありません。

## 再接続とギャップの検出

<Steps>
  <Step title="バックオフを伴う再接続">
    予想された場合でもされなかった場合でも、全ての切断で指数バックオフを伴って再接続します。サブスクリプションIDは再接続後も持続しないため、開いていたフィルターごとに`parsedTransactionSubscribe`を再送信します。
  </Step>

  <Step title="切断を越えてcontext.slotを追跡">
    切断前に見た最後の`context.slot`を保持します。再接続後に最初に見たスロットとそのスロットの間のギャップが、正確に見逃したウィンドウです — それ以上でもそれ以下でもありません。
  </Step>

  <Step title="必要に応じてバックフィル">
    アプリケーションがそのギャップを許容できない場合、RPCからそのスロットウィンドウをバックフィルしてください: 範囲内の取引を列挙するために`getSignaturesForAddress`、その後各取引を取得するために`getTransaction`を使用します。これは手動での調整ステップです — Parsed Streams自体は再生しません。
  </Step>
</Steps>

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

const URL = "wss://<ENDPOINT>/?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` | レート制限（1秒あたり10メッセージ）                                 |
| `-32006` | サブスクリプション数が多すぎる（接続ごとに25）                            |

`-32602`および`-32000`は、リクエスト自体が間違っていることを意味します - フィルターを修正し、そのまま再試行しないでください。`-32001`および`-32002`は一時的なものです。同じバックオフを使って再接続します。

## 次のステップ

<CardGroup cols={2}>
  <Card title="クイックスタート" icon="bolt" href="/docs/ja/parsed-streams/quickstart">
    フルプロトコルリファレンス: メソッド、フィルターフィールド、制限。
  </Card>

  <Card title="ジュピタースワップのトラッキング" icon="arrow-right-arrow-left" href="/docs/ja/parsed-streams/guides/track-jupiter-swaps">
    この接続がサブスクライブできるフィルターを構築します。
  </Card>
</CardGroup>
