【Laravel + Next.js】Pusherを使った双方向通信(websocket)導入手順

# やること

Laravel（API側）で"Hello,World"という文字列を送信するイベントが発火した際に、
Next.js(ブラウザ側)で自動的にリッスンして画面に"Hello,World"と表示します。

# 環境
ブラウザとAPIでサーバーを分けています。

### バックエンド（API）
PHP：8.1.24 
Laravel：9.52.15
`http://localhost:8000`

### フロントエンド（ブラウザ）
React：18.2.0 
Next.Js：13.2.4
`http://localhost:3000`



# Laravelの実装

### STEP1　pusher インストール
Pusherを使用してWebSocket通信を設定します。
pusher
```bash
composer require pusher/pusher-php-server
```
### STEP2　Pusherアカウント作成
[Pusherアカウント](https://pusher.com)を作成し、Pusherのキーを取得する。

### STEP3　.envにPusherの認証情報を追加
.env ファイルにPusherの認証情報を追加します。※BROADCAST_DRIVERは初期状態では.envの上の方にあります。

```.env
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=your-app-id
PUSHER_APP_KEY=your-app-key
PUSHER_APP_SECRET=your-app-secret
PUSHER_APP_CLUSTER=your-app-cluster
```

### STEP4　"config/app.php" ファイルのBroadcastServiceProviderのコメントアウトを外す

```app.php
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
 //↓コメントアウト外す
App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
```

### STEP5　"config/broadcasting.php" ファイルを編集

```broadcasting.php
'connections' => [
    'pusher' => [
        'driver' => 'pusher',
        'key' => env('PUSHER_APP_KEY'),
        'secret' => env('PUSHER_APP_SECRET'),
        'app_id' => env('PUSHER_APP_ID'),
        'options' => [
            'cluster' => env('PUSHER_APP_CLUSTER'),
            'useTLS' => true,
        ],
    ],
],

```

### STEP6　Pusherで使用するイベントの作成

```bash
php artisan make:event TestEvent
```

TestEvent クラスを編集します。
```broadcasting.php
class TestEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $data;

    public function __construct($data)
    {
        $this->data = $data;
    }

    public function broadcastOn()
    {
        return new Channel('test-channel');
    }

    public function broadcastAs()
    {
        return 'test-event';
    }
}
```

### STEP７　イベント発火をするルーティング作成
今回は`http://localhost:8000/test`のURLが読み込まれた際に発火するようにします。
実際に使用する際はコントローラー等、各々の発火させたい部分で行って下さい。

```web.php
Route::get('/test', function () {
    event(new TestEvent('Hello,World'));
});
```
これでLaravelの実装は完了です。

# Next.jsの実装

### STEP1　Pusherをインストール
```bash
npm install --save laravel-echo pusher-js
```

### STEP２　.env.local ファイルを作成し、Pusherのキーを設定します。

```.env.local
NEXT_PUBLIC_PUSHER_KEY=your-app-key
```

### STEP3　イベントの発火を表示するページを作る

”pages/test.tsx”ファイルを編集し、Pusherを使用するように設定します。
```test.tsx
import { useEffect, useState } from 'react';
import Pusher from 'pusher-js';
import React from 'react';

const PUSHER_KEY = process.env.NEXT_PUBLIC_PUSHER_KEY as string;

export default function Test() {
  const [data, setData] = useState('');

  useEffect(() => {
    Pusher.logToConsole = true;
    const pusher = new Pusher(PUSHER_KEY, {
      cluster: 'ap3',
    });

    const channel = pusher.subscribe('test-channel');
    channel.bind('test-event', (data) => {
      setData(JSON.stringify(data.data));
    });

    return () => {
      channel.unbind('test-event');
      pusher.unsubscribe('test-channel');
    };
  }, []);

  return <h1>{data}</h1>;
}

```

これで、Next.jsの実装　は完了です。

# 検証
`http://localhost:3000/test`を表示します。最初は何も表示されませんが、
別タブやウィンドウで`http://localhost:8000/test`を読み込みますと、`http://localhost:3000/test`に「Hello,World」と表示されます。