# 機能設計書 43-ブロードキャスト管理

## 概要

本ドキュメントは、Laravel Frameworkのブロードキャスト管理機能の設計仕様を定義する。BroadcastManagerクラスを中心とした、リアルタイムイベントのブロードキャスト機能について詳述する。

### 本機能の処理概要

ブロードキャスト管理は、サーバーサイドのイベントをWebSocket経由でクライアントにリアルタイムで配信する機能を提供する。Pusher、Ably、Redis、Reverbなど複数のブロードキャストドライバをサポートし、チャンネルベースのイベント配信とユーザー認証を管理する。

**業務上の目的・背景**：モダンなWebアプリケーションでは、リアルタイムでのデータ更新が求められる場面が多い。チャットアプリケーション、通知システム、ライブダッシュボード、コラボレーションツールなど、ユーザーにリアルタイムでフィードバックを提供することでUXが大幅に向上する。ブロードキャスト管理は、このようなリアルタイム通信を簡潔に実装できるAPIを提供する。

**機能の利用シーン**：リアルタイムチャット、通知のプッシュ配信、在庫状況のリアルタイム更新、コラボレーティブ編集、オークションサイトの価格更新、スポーツのライブスコア配信などで利用される。

**主要な処理内容**：
1. 複数のブロードキャストドライバの管理（Pusher、Ably、Redis、Reverb、Log、Null）
2. チャンネル認証ルートの登録
3. イベントのキューイングとブロードキャスト
4. プライベートチャンネル・プレゼンスチャンネルの認証
5. 匿名ブロードキャストの送信

**関連システム・外部連携**：Pusher API、Ably API、Redis Pub/Sub、Laravel Echo（フロントエンド）と連携する。

**権限による制御**：プライベートチャンネルとプレゼンスチャンネルは認証が必要。チャンネル認証コールバックで個別にアクセス制御を実装する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングにブロードキャスト管理関連の画面なし |

## 機能種別

イベント配信 / リアルタイム通信

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| event | object | Yes | ブロードキャストするイベントオブジェクト | ShouldBroadcast実装 |
| driver | string\|null | No | 使用するドライバ名 | 設定済みドライバ名 |
| channels | array\|Channel | No | 配信先チャンネル | - |

### 入力データソース

- アプリケーションコードからのイベントディスパッチ
- 設定ファイル（config/broadcasting.php）
- チャンネル認証リクエスト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| broadcast result | void | イベントの配信結果 |
| auth response | array | チャンネル認証レスポンス |

### 出力先

- 外部ブロードキャストサービス（Pusher、Ably等）
- Redis Pub/Sub
- ログファイル（Logドライバの場合）

## 処理フロー

### 処理シーケンス

```
1. イベントキューイング
   └─ queue()メソッドでイベントをキューに追加
   └─ ShouldBroadcastNowの場合は即時配信

2. 一意性チェック（ShouldBeUniqueの場合）
   └─ ロック取得を試行
   └─ 取得失敗時はスキップ

3. ドライバ解決
   └─ driver()でドライバインスタンス取得
   └─ 未解決の場合はresolve()で新規作成

4. ブロードキャスト実行
   └─ ドライバ固有のbroadcast()メソッド実行
```

### フローチャート

```mermaid
flowchart TD
    A[event発火] --> B{ShouldBroadcastNow?}
    B -->|Yes| C[dispatchNowで即時実行]
    B -->|No| D{ShouldBeUnique?}
    D -->|Yes| E{ロック取得成功?}
    E -->|No| F[スキップ]
    E -->|Yes| G[キューにプッシュ]
    D -->|No| G
    C --> H[BroadcastEvent生成]
    G --> H
    H --> I[driver解決]
    I --> J{カスタムドライバ?}
    J -->|Yes| K[callCustomCreator]
    J -->|No| L{ドライバタイプ}
    L -->|pusher/reverb| M[createPusherDriver]
    L -->|ably| N[createAblyDriver]
    L -->|redis| O[createRedisDriver]
    L -->|log| P[createLogDriver]
    L -->|null| Q[createNullDriver]
    K --> R[broadcast実行]
    M --> R
    N --> R
    O --> R
    P --> R
    Q --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-43-1 | 即時配信優先 | ShouldBroadcastNowの場合、キューを経由せず即時配信 | イベントがShouldBroadcastNow実装 |
| BR-43-2 | 一意性保証 | ShouldBeUniqueの場合、同一イベントの重複配信を防止 | イベントがShouldBeUnique実装 |
| BR-43-3 | 失敗時レスキュー | ShouldRescueの場合、例外発生時もアプリケーションを継続 | イベントがShouldRescue実装 |
| BR-43-4 | ルートキャッシュ除外 | ルートがキャッシュされている場合、routes()は何もしない | routesAreCached() が true |

### 計算ロジック

該当なし

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

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | ブロードキャスト管理自体はデータベース操作を行わない（キュー使用時はjobsテーブルを使用） |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgumentException | 接続未定義 | 指定された接続が設定されていない | config/broadcasting.phpに接続を追加 |
| InvalidArgumentException | ドライバ未サポート | 指定されたドライバがサポートされていない | サポートされているドライバを使用 |
| RuntimeException | ブロードキャスター作成失敗 | ドライバ固有のエラー（API認証失敗等） | API認証情報を確認 |

### リトライ仕様

キュー経由の場合、キューワーカーのリトライ設定に従う。

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

ブロードキャスト管理はトランザクション管理を行わない。

## パフォーマンス要件

- キュー使用時は非同期処理となりレスポンスタイムに影響しない
- 即時配信時は外部APIの応答時間に依存

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

- プライベートチャンネルは必ず認証コールバックを設定
- API認証情報は環境変数で管理
- チャンネル名にユーザー入力を直接使用しない

## 備考

- Laravel Echoとの組み合わせでフロントエンド統合が容易
- Reverbドライバは内部的にPusherドライバを使用

---

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

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

### 推奨読解順序

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

ブロードキャストマネージャーが管理する内部状態を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BroadcastManager.php | `src/Illuminate/Broadcasting/BroadcastManager.php` | プロパティ定義（37-51行目）で管理される状態を把握 |
| 1-2 | Factory.php | `src/Illuminate/Contracts/Broadcasting/Factory.php` | インターフェース定義 |

**読解のコツ**: BroadcastManagerは典型的なマネージャーパターンを採用。$driversでドライバインスタンスをキャッシュし、$customCreatorsでカスタムドライバを登録する。

#### Step 2: エントリーポイントを理解する

イベントブロードキャストの入口を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | BroadcastManager.php | `src/Illuminate/Broadcasting/BroadcastManager.php` | event() メソッド（167-170行目）でPendingBroadcast作成 |
| 2-2 | BroadcastManager.php | `src/Illuminate/Broadcasting/BroadcastManager.php` | queue() メソッド（178-216行目）がイベントをキューに追加 |

**主要処理フロー**:
1. **180-189行目**: ShouldBroadcastNowの場合は即時実行
2. **192-197行目**: broadcastQueueを決定
3. **201-206行目**: ShouldBeUniqueの場合はロック確認
4. **209-215行目**: キューにプッシュ

#### Step 3: ドライバ解決処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | BroadcastManager.php | `src/Illuminate/Broadcasting/BroadcastManager.php` | driver()（250-255行目）でドライバ取得 |
| 3-2 | BroadcastManager.php | `src/Illuminate/Broadcasting/BroadcastManager.php` | resolve()（276-299行目）でドライバ作成 |

**主要処理フロー**:
- **252行目**: 名前がなければデフォルトドライバを使用
- **254行目**: get()でキャッシュまたは新規作成
- **284-285行目**: カスタムドライバがあれば使用
- **288-291行目**: 標準ドライバはcreate{Driver}Driverメソッドで作成

#### Step 4: 各ドライバの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | BroadcastManager.php | `src/Illuminate/Broadcasting/BroadcastManager.php` | createPusherDriver()（329-332行目） |
| 4-2 | BroadcastManager.php | `src/Illuminate/Broadcasting/BroadcastManager.php` | pusher()（340-366行目）でPusherインスタンス作成 |
| 4-3 | BroadcastManager.php | `src/Illuminate/Broadcasting/BroadcastManager.php` | createRedisDriver()（396-402行目） |
| 4-4 | PusherBroadcaster.php | `src/Illuminate/Broadcasting/Broadcasters/PusherBroadcaster.php` | 実際のブロードキャスト処理 |

**主要処理フロー**:
- **342-351行目**: GuzzleClientの設定
- **353-359行目**: Pusherインスタンス作成
- **361-363行目**: ログ設定

#### Step 5: チャンネル認証を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | BroadcastManager.php | `src/Illuminate/Broadcasting/BroadcastManager.php` | routes()（69-83行目）で認証ルート登録 |
| 5-2 | BroadcastController.php | `src/Illuminate/Broadcasting/BroadcastController.php` | authenticate()でチャンネル認証実行 |

**主要処理フロー**:
- **71-73行目**: ルートキャッシュ時はスキップ
- **77-82行目**: /broadcasting/auth ルートを登録

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

```
broadcast(Event $event) [ヘルパー関数]
    │
    └─ BroadcastManager::event($event)
           │
           └─ new PendingBroadcast($events, $event)
                  │
                  └─ Event dispatch時
                         │
                         └─ BroadcastManager::queue($event)
                                │
                                ├─ [ShouldBroadcastNow]
                                │  └─ BusDispatcher::dispatchNow(BroadcastEvent)
                                │
                                └─ [通常]
                                   └─ Queue::pushOn($queue, BroadcastEvent)
                                          │
                                          └─ BroadcastEvent::handle()
                                                 │
                                                 └─ BroadcastManager::driver()
                                                        │
                                                        ├─ get($name)
                                                        │
                                                        └─ resolve($name)
                                                               │
                                                               ├─ createPusherDriver()
                                                               │      └─ pusher() → new Pusher()
                                                               │
                                                               ├─ createAblyDriver()
                                                               │      └─ ably() → new AblyRest()
                                                               │
                                                               └─ createRedisDriver()
                                                                      └─ new RedisBroadcaster()
```

### データフロー図

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

Event object     ───▶  queue()                  ───▶  BroadcastEvent
(ShouldBroadcast)       (イベントラップ)

BroadcastEvent   ───▶  Queue::push()            ───▶  jobsテーブル/Redis
(キュージョブ)          (キュー追加)

BroadcastEvent   ───▶  driver()->broadcast()    ───▶  Pusher/Ably/Redis
(ワーカー処理)          (外部サービス送信)

/broadcasting/auth ───▶ authenticate()          ───▶  認証レスポンス
(認証リクエスト)        (チャンネル認証)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| BroadcastManager.php | `src/Illuminate/Broadcasting/BroadcastManager.php` | ソース | ブロードキャストのメイン管理クラス |
| BroadcastServiceProvider.php | `src/Illuminate/Broadcasting/BroadcastServiceProvider.php` | ソース | サービスプロバイダ |
| BroadcastEvent.php | `src/Illuminate/Broadcasting/BroadcastEvent.php` | ソース | キュージョブラッパー |
| BroadcastController.php | `src/Illuminate/Broadcasting/BroadcastController.php` | ソース | 認証コントローラ |
| PusherBroadcaster.php | `src/Illuminate/Broadcasting/Broadcasters/PusherBroadcaster.php` | ソース | Pusherドライバ |
| AblyBroadcaster.php | `src/Illuminate/Broadcasting/Broadcasters/AblyBroadcaster.php` | ソース | Ablyドライバ |
| RedisBroadcaster.php | `src/Illuminate/Broadcasting/Broadcasters/RedisBroadcaster.php` | ソース | Redisドライバ |
| LogBroadcaster.php | `src/Illuminate/Broadcasting/Broadcasters/LogBroadcaster.php` | ソース | ログドライバ |
| NullBroadcaster.php | `src/Illuminate/Broadcasting/Broadcasters/NullBroadcaster.php` | ソース | Nullドライバ |
| Channel.php | `src/Illuminate/Broadcasting/Channel.php` | ソース | チャンネル基底クラス |
| PrivateChannel.php | `src/Illuminate/Broadcasting/PrivateChannel.php` | ソース | プライベートチャンネル |
| PresenceChannel.php | `src/Illuminate/Broadcasting/PresenceChannel.php` | ソース | プレゼンスチャンネル |
| AnonymousEvent.php | `src/Illuminate/Broadcasting/AnonymousEvent.php` | ソース | 匿名イベント |
| Factory.php | `src/Illuminate/Contracts/Broadcasting/Factory.php` | コントラクト | ファクトリインターフェース |
