どうも、暖冬がずっと続かないかなと思っているフリーランスプログラマのTakaです。
さて、今回は先日本業のプロジェクトでLaravelのBroadcast(ブロードキャスト)を使う機会があったのですが、初めて利用したということもあり若干手こずったので備忘録も兼ねてブロードキャストの基本的な使い方をまとめておきたいと思います。
なお、LaravelのブロードキャストはPusherを使う方法とRedisとSocket.ioを組み合わせて行う方法の2種類があるのですが、今回は後者のRedisとSocket.ioを使ってブロードキャストしていきたいと思います。
環境
なお、今回は以下の環境で試していきたいと思います。
今回の環境
- vagrant 2.2.6
- Homestead 8.0.1
- Laravel 5.8系
- Redis
- Socket.io
Homesteadのインストール
まずは、上記の環境の通り、今回は仮想環境であるHomestead上にLaravelをインストールしてブロードキャストしていきたいと思います。
HomesteadのインストールからLaravelのインストール、また基本的な設定に関しては下記の記事で紹介しているので、同じ環境で試したい方は参照してみてください。
Predisライブラリインストール
では、Laravel5.8のインストールが完了していると仮定して進めていきたいと思います。
まずは、冒頭でも述べた通り、今回はRedisを使うので下記コマンドでPredisライブラリをインストールします。
Socket.ioインストール
続いて、ソケット通信が必要なためSocket.ioもインストールします。
laravel-echoのインストール
続いて、イベントブロードキャストのリッスンをサポートしてくれるlaravel-echoというJavascriptのライブラリをインストールします。イベントブロードキャストのリッスンなので、要はフロント側というか、RedisのPub/Subで言うとSub側の面倒な処理を担ってくれるライブラリですね。
composer.jsonとpackage.jsonを確認
ここまでインストールしたら、一旦このタイミングでインストールしたライブラリがインストールされている確認しておきましょう。
まず、Predisライブラリはcomposer.jsonに追記されるので、下記のように「require」の中に追記されていれば大丈夫です。
Socket.ioとlaravel-echoに関してはpackage.jsonに追記されるので、下記のように「dependencies」に追記されていれば大丈夫です。
larval-echo-serverインストール
続いて、下記コマンドでlarval-echo-serverをインストールしていきます。
laravel-echo-serverは、LaravelのブロードキャストにおいてWebsocketサーバを立ててくれるパッケージのようなもので、中身はNode.jsで書かれています(はず)。Websocket通信をやりたい場合はSocket.ioを使ったとしても自分でNode.jsをゴリゴリ書かないといけないのですが、laravl-echo-serverはこの本来はNode.jsでやらないといけない部分を一手に担ってくれます。さきほどインストールしたlaravel-echoはJavascriptのライブラリと説明しましたが、要するにRedisとJavascriptの連携部分の面倒なことをやってくれてるという認識でいいのではないかと思います。(間違ってたらご指摘くださいmm)
なお、laravel-echo-serverは上記の通り、グローバル環境にインストールしてください。
BroadcastServiceProviderを有効化
laravel-echo-serverのインストールが終わったら、「config/app.php」を開いてBroadcastServiceProviderを有効化します。
環境変数を設定
ここまで問題なくできたら、ブロードキャストをRedisで行うために.envファイル開いて下記2つの環境変数に「redis」を指定します。
変更が必要な環境変数
- BROADCAST_DRIVER
- QUEUE_CONNECTION
Redisのprefixを編集
続いて、「config/database.php」を開いて「redis」の「options」にある「prefix」を下記のように空白に修正してください。
このprefixの扱いについて公式のドキュメントには記載がなく、小一時間ハマりましたね。。
larval-echo-serverの初期化設定
ここまで設定したら、このタイミングでlarval-echo-serverの初期化設定を下記コマンドで行います。
いろいろ質問されますが、ご自身の環境に合わせて答えてください。ポート番号も別で使っていなければデフォルトの6001でも問題ないと思います。
larval-echo-serverの起動
初期化設定が完了したら、実際に下記コマンドでlarval-echo-serverを起動してみます。
問題なく起動に成功したら、下記のように表示されると思います。(ポート番号はinitで設定したポート)
起動確認ができたら一旦laravel-echo-serverを終了させておきます。
Eventの作成
続いて、実際にブロードキャストしたいイベントを作成していきます。
まずは、下記artisanコマンドでEventファイルを作成します。イベント名は任意の名前で大丈夫です。
ここでは、「SampleEvent」と命名したいと思います。
ShouldBroadcastの継承
上記コマンドでイベントファイルを作成したら、「app/Events」配下にイベントファイル(ここではSampleEvent.php)が出来ていると思うので、このファイルを開いて「ShouldBroadcast」を下記のように継承します。
チャンネルの設定
続いて、ブロードキャストするチャンネルの設定をしていきます。
イベントファイルのソースコードを見てもらえれば分かると思うのですが、チャンネルは「broadcastOn」関数で設定されています。
artisanコマンドで作成したイベントファイルはデフォルトでPrivateChannelになっているのですが、今回はPrivateChannelではなく便宜上、通常のChannelで進めていきたいので、下記のようにPrivateChannelをChannelに変更します。
また、合わせてチャンネル名も同時に設定したいと思います。ここでは下記のとおり、「test-socket」というチャンネル名にしたいと思います。
Redisに渡したいデータの設定
チャンネルの設定をしたら、今度は実際にRedisに送信したいデータの設定をします。
渡したいデータはbroadcastWithメソッドで設定できるので、下記のように設定します。今回は「データを送信したよ」というサンプルデータをブロードキャストしたいと思います。
イベントをブロードキャストする
イベントの設定を諸々したら、実際にRedisにイベントをブロードキャストしてみます。
ブロードキャストはevent関数で渡すことができるので、今回は「/sample」ページにアクセスがあった際にデータをブロードキャストするようにルーティングのweb.phpに下記のように記載したいと思います。
bootstrap.jsの設定
バックエンド側のブロードキャスト設定をしたら、続いて受け取る側の設定もしていきます。
まずは、「resources/js/bootstrap.js」を開いて下記のコードを追記します。47〜53行目は決まり文句のような感じですが、52行目のポート番号はlaravel-echo-serverの初期化で設定したポート番号を設定してください。
55〜58行目では、イベントファイルで作成したチャンネルをここで共有しイベントをリッスンして、バックエンドから送られてきたデータをコンソールの表示するようにしています。
CSRFトークンの読み込み
続いて、「/sample」ページにアクセスした際にブロードキャストされるデータをコンソールで表示したいので、とりあえずトップページのbladeである、「welcome.blade」を開いて下記のコードをhead内に記載しCSRFトークンを読み込みます。
scriptトークンの読み込み
さらに、ブロードキャストのデータをリッスンするためにはapp.jsも必要になるので、これもwelcome.blade内のbodyの閉じタグの直前で読み込みます。head内に記載したい場合はdefer属性を付与して読み込んでください。
javascriptのコンパイル
最後に、今回は上記の通りapp.jsも使うので、先ほど編集したbootstrap.jsの内容を反映させるために下記コマンドでコンパイルします。
queueの実行
これで諸々の設定は完了になります。
ここまで設定したら、改めてlaravel-echo-serverを起動します。
そして、下記コマンドでqueueを動かせばブロードキャストできるようになっていると思います。なお、sleepオプションは必須ではありません。ここでは1秒間隔で監視したいのでsleepタイムに1秒を設定しています。
念のため、確認方法まで説明しておくと、トップページを開いてデベロッパーツールでコンソール画面を開いておいて、別タブ(or ウィンドウ)で「/sample」ページにアクセスすると、トップページのコンソール画面にデータが表示されるのが確認できるかと思います。
まとめ
ということで、今回はLaravelのBroadcast機能(Redis+Socket.io)について備忘録も兼ねて基礎的なブロードキャスト方法を紹介させていただきました。いくつかハマりポイントがあったので、もし参考になれば。
てことで、今回はここまで!また!