サーバーとクライアント間での双方向通信を可能にするライブラリであるLaravel Echo。
チャット機能などを実装する際のリアルタイム通信のためにも使われたりするこのライブラリですが、先日実務で使用した際にふと「どういう仕組みで動いているんだろう」と気になりました。
そもそも僕自身これまでLaravel Echoは「何となくコピペしたらいい感じに動いた」くらいの知識と経験しかないので、これを機会に少し勉強してみようかと思い、この記事を書いています。
僕と同じくらいのレベル感の人が「Laravel Echoってそういう感じなのね」と思ってくれるような記事になれば幸いです。
そんな感じで早速Laravel Echoについて調べていきます。
まず公式ドキュメントをみてみよう
公式ドキュメントによるとLaravel Echoは以下のようなものらしいです。
Laravel 8.x ブロードキャスト
LaravelはWebSocket接続を介してサーバ側のLaravelイベントを簡単に「ブロードキャスト」できます。Laravelイベントをブロードキャストすると、サーバ側のLaravelアプリケーションとクライアント側のJavaScriptアプリケーション間で同じイベント名とデータを共有できます。
ブロードキャストの基本的なコンセプトは簡単で、クライアントはフロントエンドで指定されたチャンネルに接続し、Laravelアプリケーションはバックエンドでこれらのチャンネルにイベントをブロードキャストします。これらのイベントには、フロントエンドで利用可能にしたい追加データを含めることができます。
何言ってるんですかねこれ?
知識のある方ならすんなり理解できるのでしょうが、WebSocket接続やらイベントやらチャンネルやら分かりそうで分からない単語が多くて、僕にとってはめまいがしそうな一文でした。
この一文が難解なのはおそらくカタカナの用語の意味が難しくていまいちよく分からないからだと思います。なのでまずは一つずつその用語を調べてみようかなと思います。
今回は以下の4単語
- WebSocket接続
- イベント
- ブロードキャスト
- チャンネル
について調べてみようと思います。
WebSocket接続
WebSocket接続についてはこの記事がとても参考になりました。
どうやらWebSocket接続とは「双方向通信を行うためのプロトコル」のようです。
みんなおなじみHTTP通信の場合は大雑把にいえばコネクション確立→通信→コネクション終了
のような流れで通信を行うようですが、WebSocket通信の場合はコネクション接続⇨双方向に通信⇨通信後もコネクションは終了しないので何度でも通信できる
といった形なので、何度も通信できるというわけですね。
イベント
イベントはその名の通り「イベント」でどうやらLaravel内で自分で設定するもののようです。
イベントとリスナーについては下記記事がとても参考になりました。
上記記事に従って簡単に説明すると、例えば「ユーザーが会員登録を完了した」というイベントを作成したとしましょう。
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
// ユーザーが会員登録を完了したイベントを発生
event(new UserRegistered($user));
return $user;
}
これに対してUserRegisteredイベントをリッスンするように下記コードを書くと、そのイベントが発生した時に特定の処理を実行できるということなんですね。
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use App\Events\UserRegistered;
use App\Listeners\SendWelcomeEmail;
use App\Listeners\RegisterMailMagazine;
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
// 会員登録した時にSendWelcomeEmailとRegisterMailMagazineを実行!!
UserRegistered::class => [
SendWelcomeEmail::class,
RegisterMailMagazine::class,
],
];
public function boot()
{
parent::boot();
//
}
}
もちろん普通にevent(new UserRegistered($user));
の代わりにそれぞれのメールを送信する処理を書いても結果としては同じ動きにはなります。
ただ、Eventにした方がその処理の意味合いに近いため、理解しやすくコードも見やすいいわゆる保守性の高いコードになるのかなと思います。
軽く脱線した感がいなめないですがイベントはこんな感じの概念でした。
ブロードキャスト
ブロードキャスト(broadcast)は直訳すると放送する、広める
といった意味になります。
まあそのままの意味で捉えてもよさそうなのですが、もう少しIT用語的にいうと一つのサーバーから同じネットワーク内にいる多数のクライアントに通信するといった意味なようです。
チャンネル
最後にチャンネルです。チャンネルもブロードキャストと同様にそのままの意味で捉えて良さそうです。
1番分かりやすいのはやはりテレビですかね。テレビはチャンネルごとにそれぞれ放送をテレビ局から各家庭に向けて配信しています。
これを各家庭ではチャンネルを合わせることで実際にテレビ画面に表示されます。
このように配信(ブロードキャスト)されているデータの中で特定のまとまりをもったものをチャネルと呼ぶようです。
全部調べたのでもう一度公式ドキュメントを読んでみよう
というわけで良く分からなかった単語を全て調べることができたので、改めて公式ドキュメントの問題の一文を読んでみましょう。
Laravel 8.x ブロードキャスト
LaravelはWebSocket接続を介してサーバ側のLaravelイベントを簡単に「ブロードキャスト」できます。
これはつまり噛み砕いて書くと
Laravel 8.x ブロードキャスト
Laravelはサーバーとクライアント間の双方向通信を行うためのコネクションを作成し、そのコネクションを介してサーバ側の任意のタイミングで発火したLaravelイベントを簡単に多数のユーザーに同時に届けることができます。
くらいの感じになるのかなと思います。(この後の文もうまく噛み砕いた説明をしたかったのですが無理でした。)
何となく理解が深まった
どうですかみなさん。僕はそれなりに理解が深まったのでみなさんも何となく理解が深まってくれたら嬉しいのですがいかがでしょう。
個人的に結構大事なポイントだなと感じたのは
- サーバーから多数に向けて同時に配信する
という点でした。
実際にアプリでLaravel Echoを使う時の多くはチャット機能のように特定のユーザーにしか配信したくない情報をブロードキャストする
ことが多いのかなと思います。
サーバーとクライアントが1:1で接続を確立することができれば特に問題ないのですが、ブロードキャストの場合は同じネットワーク内にいるクライアント全てに配信してしまうので、特定のユーザーごとにチャンネルを切り分ける
ということがとても重要になるんだなと思います。
このチャンネルの切り分け方は実装する時に結構センスが問われそうなところではあるので、色々とまた試してみたいなと思いました。(同じチャンネル内で配信するデータのプロパティを元にクライアント側で処理を分岐するのか、それともそもそもチャンネルをユーザーごとに分けるのか、など)
ちなみにチャンネルといえばLaravel Echoの公式ドキュメントにも記載されているプライベートチャンネルとパブリックチャンネルですが、これは
- プライベートチャンネル・・・認証・認可されたユーザーのみ購読可能
- パブリックチャンネル・・・全てのユーザーが購読可能
というだけで、少し名前が紛らわしいので要注意です。
最後に
以上Laravel Echoについてでした。分からないところがあればコメントいただければ分かる範囲で答えますのでよろしくお願いします。
ありがとうございました!