戻る
2022-11-23
Laravel

Laravel Sail+Horizonでのブロードキャスト機能開発環境の構築

あくまで開発環境までの話。本番環境で動かす話は含まない。

  1. 環境
  2. 新規プロジェクト作成
  3. config/app.php
  4. Breezeインストール
  5. Horizonインストール
  6. Sail起動
  7. Laravel WebSocketsインストール
  8. Larave Echoインストール
  9. ここまでの動作確認
  10. 新規ユーザーを作成
  11. PresenceChannel
  12. PrivateChannel
  13. 最後の動作確認
  14. 片付け
  15. 終わり

環境

  • Laravel 9.x (Vite移行後)
  • PHP 8.1
  • Sail 1.16 (./vendor/bin/sailはsailと表記)
  • Breeze 1.15
  • Horizon 5.10
  • laravel-websockets 1.13.1
  • pusher/pusher-php-server 7.0.2 (これを書いてる時点では7.2.1では動かないので7.0.2に固定)

将来のバージョンではこのまま真似しても動かない可能性が高いので注意。

新規プロジェクト作成

何も指定してないデフォルトだけどwith=mysql,redis,meilisearch,mailhog,seleniumと同等。Horizonのためにredisは必須。

curl -s "https://laravel.build/sail-broadcast-project" | bash

いつの間にか作成時にsail buildも実行されるようになっている。すでにsail使っている場合には余計。

config/app.php

BroadcastServiceProviderを使うようにコメントを外す。

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,

Breezeインストール

PrivateChannelやPresenceChannelも試したいのでスターターキットをインストール。今回はBreezeのVue版。好きなスターターキットを使えばいい。ReactならEchoを使うのでほとんど同じ。Livewireなら

A full-stack framework for Laravel that takes the pain out of building dynamic UIs.

composer require laravel/breeze --dev

php artisan breeze:install vue

これもいつの間にかnpm inpm run buildまで自動で実行される。

Horizonインストール

ブロードキャストはキューが使えることが前提。開発時はsyncドライバーでもいいけどきちんと非同期で動かしたいのでHorizonをインストール。

composer require laravel/horizon

php artisan horizon:install

.envを修正。

QUEUE_CONNECTION=redis

docker-compose.ymlを修正。laravel.testとmysqlの間に同じようにhorizonを追加。

    horizon:
      image: sail-8.1/app
      environment:
        WWWUSER: '${WWWUSER}'
        LARAVEL_SAIL: 1
      volumes:
        - '.:/var/www/html'
      command: php artisan horizon
      restart: always
      networks:
        - sail
      depends_on:
        - mysql
        - redis

image: sail-8.1/appはlaravel.testと合わせる。

Sail起動

migrateしてviteのdevサーバー起動。

sail up -d

sail art migrate
npm run dev

devサーバーはsail内でも外でもどっちで実行してもいい。 sail内で実行してエラーが出る場合、sailで再度インストールし直す。

sail npm i

sail npm run dev

以降はこの状態で進める。ただし必要な時は再起動。horizonでコードの変更が反映されない時は起動し直す。

sail up -d

もしくは

sail art horizon:terminate

horizonに再起動コマンドはない。終了したら何らかの方法で自動的に再起動する設定で使う前提。

Laravel WebSocketsインストール

We focus on building tools that make your life as developer more enjoyable and love sharing our broad knowledge that we gain during this process.

composer require beyondcode/laravel-websockets

php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"

sail art migrate

php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"

.envを修正。PUSHER_APP辺りはなんでも良さそう。

BROADCAST_DRIVER=pusher

PUSHER_APP_ID=test
PUSHER_APP_KEY=test
PUSHER_APP_SECRET=test
PUSHER_HOST=websockets
PUSHER_PORT=6001
PUSHER_SCHEME=http

config/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'),
                'encrypted' => true,
                'host' => env('PUSHER_HOST', '127.0.0.1'),
                'port' => env('PUSHER_PORT', 6001),
                'scheme' => env('PUSHER_SCHEME', 'http')
            ],
            'client_options' => [
                // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
            ],
        ],

docker-compose.ymlを修正。websocketsはsail内で実行するのでportsが必要。

    websockets:
        image: sail-8.1/app
        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
        ports:
            - '${PUSHER_PORT:-6001}:${PUSHER_PORT:-6001}'
        volumes:
            - '.:/var/www/html'
        command: php artisan websockets:serve
        restart: always
        networks:
            - sail
        depends_on:
            - mysql
            - redis

bootstrap.jsは次で。

Larave Echoインストール

npm i -D laravel-echo pusher-js

bootstrap.jsを修正。

import Echo from 'laravel-echo';

import Pusher from 'pusher-js';
window.Pusher = Pusher;

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'test',
    wsHost: window.location.hostname,
    wsPort: import.meta.env.VITE_PUSHER_PORT,
    forceTLS: false,
    disableStats: true,
});

window.location.hostnamelocalhostになる。

  • Echo側:sailの外からlocalhost:6001で接続。
  • laravel.testやhorizon:sail内からwebsockets:6001で接続。

若干ややこしいのでそれぞれがどこで動作していてどう繋がっているか理解していないと設定で間違う。

ここまでの動作確認

一応sailやvite devサーバーを再起動してから

horizonとwebsocketsはsail内で実行、devサーバーはどちらでも問題ないことを確認できたら次へ。

ここまでで開発環境の構築は完了。

新規ユーザーを作成

ここからはブロードキャスト機能の確認。

簡易的なのでチャットっぽいものを作るだけ。DBにログは残さずその場だけのチャット。

  • PresenceChannel : ログイン中のユーザー共通のチャット。
  • PrivateChannel : 自分だけのチャット。

PresenceChannel

長くなったのでコードはGitHubで。

処理の流れ

  1. DashboardのPresenceChannel.vueを表示したらEcho.join('presence')でPresenceChannelに参加。
  2. フォームからチャットを送信。
  3. Laravel側のPresenceController→PresenceSubmitと進んでPresenceSubmitからブロードキャスト。
  4. フロント側に戻ってきて.listen('PresenceSubmit',で受信。

VueかReactで変わる表示部分は重要ではないのでこの流れを理解。

PrivateChannel

PresenceChannelとほとんど同じなのでファイルをコピーしてPrivateChannel用を作成。

最後の動作確認

2ユーザー作ってPresenceChannelには両方のチャットが表示、PrivateChannelには送信したユーザーだけ表示されることを確認。

チャットならイベントのShouldBroadcastShouldBroadcastNowにしたほうがすぐに反映されていいかもしれない。この辺りは用途次第。

片付け

終了時は

sail down

viteはCtrl+Cで終了。

終わり

ここまでできれば後はLaravelのドキュメントを見てブロードキャスト機能を使っていける。

投稿者 Invokable
コメントを書くにはログインしてください。
登録 ログイン