Laravel Echoを使ってメッセージをリアルタイムで送信する(後編)

前回の記事で、LaravelEchoを準備する方法について解説しました。

今回は、実際にLaravelEchoの処理をLaravelプロジェクト上に実装して動くようにしていきたいと思います。

まず、先日生成したlaravel-echo-server.jsonの内容を確認していきます。

下記のような内容になっていればOKです。違った内容や未入力の内容がある場合はjsonファイルを直接編集して修正します。

{
	"authHost": "https://LaravelEchoServerが動作するサーバーのホスト名",
	"authEndpoint": "/broadcasting/auth",
	"clients": [
		{
			"appId": "省略(デフォルトで入ってます。)",
			"key": "省略(デフォルトで入ってます。)"
		}
	],
	"database": "redis",
	"databaseConfig": {
		"redis": {
			"host" : "redisサーバーのipもしくはFQDN"
		},
		"sqlite": {
			"databasePath": "databaseにsqliteを指定した場合はここにDBファイルのパスを入れる"
		}
	},
	"devMode": true,
	"host": null,
	"port": "6001",
	"protocol": "https",
	"socketio": {},
	"secureOptions": 67108864,
	"sslCertPath": "SSL証明書のパス",
	"sslKeyPath": "SSL証明書秘密鍵のパス",
	"sslCertChainPath": "SSL中間証明書のパス(必要であれば)",
	"sslPassphrase": "SSL証明書秘密鍵のパスワード(必要であれば)",
	"subscribers": {
		"http": true,
		"redis": true
	},
	"apiOriginAllow": {
		"allowCors": true,
		"allowOrigin": "https://LaravelEchoServerが動作するサーバーのホスト名",
		"allowMethods": "GET, POST",
		"allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"
	}
}

laravel-echo-server.jsonはこれでOKです。

Laravel Echoのしくみを起動させる前に先に他の部分も設定していきます。 

プロジェクトルート/config/app.phpの"Application Service Providers..."コメントの真下にあるブロック中の
//App\Providers\BroadcastServiceProvider::class,

のコメントアウトを外します。

App\Providers\BroadcastServiceProvider::class, //コメントアウトを外した状態

次に、.envを変更します。
設定値のうち、下記の2項目の値を”redis”に変えます。

BROADCAST_DRIVER=redis

QUEUE_CONNECTION=redis

.envの書き換えが終わったら、次のコマンドを実行します。

php artisan make:event PublicEvent

すると、プロジェクトルート/app/Events/にPublicEvent.phpが生成されます。

このファイルがWebsocketで送信するメッセージの設定内容になります。

broadcastOn()とbroadcastWith()を下記の例のように編集します。(日本語部分を任意のものに置き換えてください。)

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class PublicEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel('通知のチャンネル名');
    }

    public function broadcastWith()
    {
        return [
            'message' => 'ブラウザに送信するメッセージ',
        ];
    }
}

上記のイベントファイルの記述が終わったら、コントローラー上のメッセージを送信させたい部分のところに、次のメソッドを入れます。(Controllerのルートはすでに記述済みとします。)

...省略...
use App\Events\PublicEvent;
...省略...

class HogeController extends Controller
{
    public function photoStore(Request $request){

        ...省略※1...
        event(new PublicEvent()); //ここで、さっきのプロジェクトルート/app/Events/PublicEvent.phpで指定したメッセージがブラウザに送信される。
        ...省略...
    }

}

ここまで定義が終わったら、フロントエンド側でWebsocketに接続するためのロジックを記述します。

“プロジェクトルート/resources/js/app.js”もしくは”プロジェクトルート/resources/js/bootstrap.js”に次のコードを記述します。

//Websocket接続処理
import Echo from 'laravel-echo';
window.io = require('socket.io-client');
window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: 'https://WebsocketサーバーのFQDN',
});

最後に、サーバーからWebsocket経由でメッセージを受け取ったときの処理を記述します。

 window.Echo.channel('event-lib')
                    .listen('PublicEvent', (e) => {
                       //サーバーからWebsocket経由でメッセージが送られたときにさせたい処理。下記の一行は例。
                       alert('サーバーからのメッセージ', e.message);
                    })
//※実際は万が一接続が切れてしまった場合に、何らかのタイミング(ブラウザにフォーカスがあたったなどのイベント発生時やタイマーなど)で再接続を行うように上記のロジックを書く必要があります。

上記の処理は、app.js もしくは bootstrap.jsに記述すればサイト全体で反映されますし、特定のページのみで動作させたい場合は、各ページのみが参照するJavascriptに記述すればOKです。

ここまでできたら、実際に稼働させてみましょう。

プロジェクトルートにカレントディレクトリを移動し、次のコマンドを管理者権限で実行します。

laravel-echo-server start & php artisan queue:work

この状態で、最初に記述したコントローラーの ※1の処理が終わったあとでメッセージが表示され、アラートがブラウザ上に表示されればWebsocketの実装は成功です。

停止する場合はctrl+cを押したあとで、管理者権限で次のコマンドを入力します。

laravel-echo-server stop

お疲れさまでした…!

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG