Laravel9 Sail+Horizonでのブロードキャスト機能開発環境の構築
2年前の記事です。
Laravelは古い情報は全く役に立たないので絶対に参考にしないでください。
コメントに新しい情報がないか確認してください。
Laravel11 Sail+Reverbバージョン
- 以降は古い記事
- 環境
- 新規プロジェクト作成
- config/app.php
- Breezeインストール
- Horizonインストール
- Sail起動
- Laravel WebSocketsインストール
- Larave Echoインストール
- ここまでの動作確認
- 新規ユーザーを作成
- PresenceChannel
- PrivateChannel
- 最後の動作確認
- 片付け
- 終わり
以降は古い記事
あくまで開発環境までの話。本番環境で動かす話は含まない。
環境
- Laravel 9.x (Vite移行後)
- PHP 8.1
- Sail 1.16 (./vendor/bin/sailはsailと表記)
- Breeze 1.15
- Horizon 5.10
- laravel-websockets 1.13.2
- pusher/pusher-php-server 7.2.2 (
これを書いてる時点では7.2.1では動かないので7.0.2に固定laravel-websockets 1.13.2で修正されたので7.2.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なら
composer require laravel/breeze --dev
php artisan breeze:install vue
これもいつの間にかnpm i
とnpm 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インストール
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.hostname
はlocalhost
になる。
- Echo側:sailの外からlocalhost:6001で接続。
- laravel.testやhorizon:sail内からwebsockets:6001で接続。
若干ややこしいのでそれぞれがどこで動作していてどう繋がっているか理解していないと設定で間違う。
ここまでの動作確認
一応sailやvite devサーバーを再起動してから
- http://localhost/
- http://localhost/horizon
- http://localhost/laravel-websockets 「Connect」で接続できるかテスト
horizonとwebsocketsはsail内で実行、devサーバーはどちらでも問題ないことを確認できたら次へ。
ここまでで開発環境の構築は完了。
新規ユーザーを作成
ここからはブロードキャスト機能の確認。
簡易的なのでチャットっぽいものを作るだけ。DBにログは残さずその場だけのチャット。
- PresenceChannel : ログイン中のユーザー共通のチャット。
- PrivateChannel : 自分だけのチャット。
PresenceChannel
長くなったのでコードはGitHubで。
処理の流れ
- DashboardのPresenceChannel.vueを表示したら
Echo.join('presence')
でPresenceChannelに参加。 - フォームからチャットを送信。
- Laravel側のPresenceController→PresenceSubmitと進んでPresenceSubmitからブロードキャスト。
- フロント側に戻ってきて
.listen('PresenceSubmit',
で受信。
VueかReactで変わる表示部分は重要ではないのでこの流れを理解。
PrivateChannel
PresenceChannelとほとんど同じなのでファイルをコピーしてPrivateChannel用を作成。
最後の動作確認
2ユーザー作ってPresenceChannelには両方のチャットが表示、PrivateChannelには送信したユーザーだけ表示されることを確認。
チャットならイベントのShouldBroadcast
をShouldBroadcastNow
にしたほうがすぐに反映されていいかもしれない。この辺りは用途次第。
片付け
終了時は
sail down
viteはCtrl+Cで終了。
終わり
ここまでできれば後はLaravelのドキュメントを見てブロードキャスト機能を使っていける。