# 機能設計書 56-WebSocket

## 概要

本ドキュメントは、BunのWebSocketサーバーおよびクライアント機能の設計仕様を記述する。

### 本機能の処理概要

BunのWebSocket機能は、サーバーサイド（Bun.serve内のwebsocketオプション）とクライアントサイド（標準WebSocket API）の両方をサポートする。uWebSocketsベースの高性能WebSocket実装により、リアルタイム通信を実現する。

**業務上の目的・背景**：リアルタイムWebアプリケーション（チャット、通知、ゲーム等）に不可欠なWebSocket通信を、高性能かつシンプルなAPIで提供する。

**機能の利用シーン**：リアルタイムチャットアプリケーション、通知システム、オンラインゲーム、リアルタイムダッシュボード、IoTデータストリーミング。

**主要な処理内容**：
1. WebSocketサーバーの設定（Bun.serve内）
2. HTTPからWebSocketへのアップグレード
3. メッセージの送受信（テキスト/バイナリ）
4. Pub/Subによるトピックベースのブロードキャスト
5. 接続の管理とクローズ処理

**関連システム・外部連携**：uWebSockets（C++ライブラリ）、Bun.serve（HTTPサーバー）。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | サーバー/クライアントAPIによるプログラマティック操作 |

## 機能種別

ネットワーク / リアルタイム通信

## 入力仕様

### サーバーサイド設定（websocketオプション）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| open | function | No | 接続オープン時のコールバック | - |
| message | function | Yes | メッセージ受信時のコールバック | 必須 |
| close | function | No | 接続クローズ時のコールバック | - |
| drain | function | No | バッファドレイン時のコールバック | - |
| ping | function | No | Ping受信時のコールバック | - |
| pong | function | No | Pong受信時のコールバック | - |
| maxPayloadLength | number | No | 最大ペイロードサイズ | - |
| idleTimeout | number | No | アイドルタイムアウト（秒） | - |
| backpressureLimit | number | No | バックプレッシャー制限 | - |
| compression | boolean | No | 圧縮有効化 | - |

### クライアントサイドAPI

```javascript
const ws = new WebSocket(url, protocols);
ws.onopen = (event) => { };
ws.onmessage = (event) => { };
ws.onclose = (event) => { };
ws.onerror = (event) => { };
ws.send(data);
ws.close(code, reason);
```

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| message | string/ArrayBuffer | 受信メッセージ |
| data | object | WebSocketに紐付くカスタムデータ |

### ServerWebSocketメソッド

```typescript
interface ServerWebSocket {
  send(message: string | ArrayBuffer, compress?: boolean): number;
  sendText(message: string, compress?: boolean): number;
  sendBinary(message: ArrayBuffer, compress?: boolean): number;
  close(code?: number, reason?: string): void;
  subscribe(topic: string): void;
  unsubscribe(topic: string): void;
  publish(topic: string, message: string | ArrayBuffer): number;
  isSubscribed(topic: string): boolean;
  cork(callback: () => void): void;
  ping(data?: ArrayBuffer): number;
  pong(data?: ArrayBuffer): number;
  data: any;
  readyState: number;
  binaryType: "nodebuffer" | "arraybuffer" | "uint8array";
  remoteAddress: string;
}
```

## 処理フロー

### 処理シーケンス（サーバーサイド）

```
1. Bun.serve()でwebsocketオプション設定
   └─ WebSocketServer.Handler生成
2. HTTPリクエスト受信
   └─ Upgrade: websocketヘッダー検出
3. server.upgrade(req)呼び出し
   └─ WebSocketハンドシェイク
4. onOpen コールバック
   └─ ServerWebSocket生成
5. メッセージ受信
   └─ onMessage コールバック
6. メッセージ送信
   └─ ws.send() / ws.publish()
7. 接続クローズ
   └─ onClose コールバック
```

### フローチャート

```mermaid
flowchart TD
    A[HTTPリクエスト] --> B{Upgradeヘッダー?}
    B -->|No| C[通常HTTP処理]
    B -->|Yes| D[server.upgrade]
    D --> E{アップグレード成功?}
    E -->|No| F[エラー応答]
    E -->|Yes| G[onOpen]
    G --> H[接続維持]
    H --> I{イベント種別}
    I -->|message| J[onMessage]
    I -->|ping| K[onPing]
    I -->|pong| L[onPong]
    I -->|drain| M[onDrain]
    I -->|close| N[onClose]
    J --> H
    K --> H
    L --> H
    M --> H
    N --> O[接続終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-56-1 | アップグレード必須 | WebSocket使用にはHTTPアップグレードが必要 | サーバーサイド |
| BR-56-2 | messageコールバック必須 | messageハンドラーは必須 | サーバーサイド |
| BR-56-3 | Pub/Sub | subscribe/publishでトピックベースの配信 | Pub/Sub使用時 |
| BR-56-4 | binaryType | 受信バイナリのデフォルトはBuffer | メッセージ受信時 |

### Opcode

```
Continue = 0x0
Text = 0x1
Binary = 0x2
Close = 0x8
Ping = 0x9
Pong = 0xA
```

## データベース操作仕様

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1000 | NormalClosure | 正常終了 | - |
| 1001 | GoingAway | サーバー/クライアント退去 | 再接続 |
| 1002 | ProtocolError | プロトコルエラー | プロトコル確認 |
| 1003 | UnsupportedData | 非対応データ型 | データ形式確認 |

### リトライ仕様

クライアントサイドでの自動再接続はアプリケーション側で実装。

## トランザクション仕様

該当なし。

## パフォーマンス要件

- メッセージレイテンシ：サブミリ秒
- 同時接続：数万接続をサポート
- cork()による送信バッファリング最適化

## セキュリティ考慮事項

- wss://（WebSocket Secure）でTLS暗号化
- Origin検証の実装推奨
- メッセージサイズ制限（maxPayloadLength）

## 備考

- WebSocket圧縮（permessage-deflate）対応
- バックプレッシャー管理でメモリ保護
- AbortSignalによるキャンセル対応

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、WebSocketの基本データ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | websocket.zig | `src/http/websocket.zig` | Opcode、WebsocketHeader |
| 1-2 | ServerWebSocket.zig | `src/bun.js/api/server/ServerWebSocket.zig` | ServerWebSocket構造体 |

**読解のコツ**: WebsocketHeaderはpacked structでフレームヘッダーを表現している。

**主要処理フロー**:
- **4-25行目** (websocket.zig): Opcode enum定義
- **27-86行目** (websocket.zig): WebsocketHeader packed struct
- **1-60行目** (ServerWebSocket.zig): ServerWebSocket構造体とFlags

#### Step 2: サーバーサイド処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ServerWebSocket.zig | `src/bun.js/api/server/ServerWebSocket.zig` | イベントハンドラー |

**主要処理フロー**:
- **63-117行目**: onOpen関数。接続オープン時の処理
- **119-179行目**: onMessage関数。メッセージ受信時の処理
- **185-211行目**: onDrain関数。バッファドレイン時の処理
- **285-300行目**: onClose関数。接続クローズ時の処理

#### Step 3: アップグレード処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | server.zig | `src/bun.js/api/server.zig` | onUpgrade関数 |

**主要処理フロー**:
- **746-999行目**: onUpgrade関数。HTTPからWebSocketへのアップグレード

#### Step 4: Pub/Sub処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | server.zig | `src/bun.js/api/server.zig` | publish関数 |

**主要処理フロー**:
- **700-744行目**: publish関数。トピックへのメッセージブロードキャスト

### プログラム呼び出し階層図

```
Bun.serve({ websocket: {...} })
    │
    ├─ WebSocketServer.Handler生成
    │
    └─ server.upgrade(req)
           │
           └─ uws.upgradeToWebSocket
                  │
                  └─ ServerWebSocket
                         ├─ onOpen
                         ├─ onMessage
                         │      └─ binaryToJS (Buffer/Uint8Array変換)
                         ├─ onPing
                         ├─ onPong
                         ├─ onDrain
                         └─ onClose
```

### データフロー図

```
[入力]                    [処理]                           [出力]

HTTPリクエスト ────────▶ Upgrade検出 ──────────▶ WebSocketハンドシェイク
(Upgrade: websocket)           │
                               ▼
                        ServerWebSocket生成
                               │
                               ▼
クライアントメッセージ ─▶ onMessage ─────────────▶ アプリケーション処理
                               │
                               ▼
ws.send() ─────────────▶ uws送信 ───────────────▶ クライアント
                               │
ws.publish(topic) ─────▶ uws.publishWithOptions ▶ 購読者全員
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ServerWebSocket.zig | `src/bun.js/api/server/ServerWebSocket.zig` | ソース | WebSocketサーバー実装 |
| websocket.zig | `src/http/websocket.zig` | ソース | WebSocketプロトコル定義 |
| server.zig | `src/bun.js/api/server.zig` | ソース | upgrade/publish処理 |
| WebSocketServerContext.zig | `src/bun.js/api/server/WebSocketServerContext.zig` | ソース | WebSocket設定コンテキスト |
| websocket_client.zig | `src/http/websocket_client.zig` | ソース | WebSocketクライアント |
