【Laravel】リアルタイムのチャットを実装💬
LaravelのBroadcast、Pusher、およびLaravel Echoを使用することで、リアルタイムなチャット機能を簡単に実装することができます。この記事では、セットアップからチャット機能の実装、その後の機能拡張までの手順を解説します。ご自身のWebサービスでユーザーとのリアルタイムなコミュニケーションを実現したい方は是非参考にしてみてください。
1. はじめに
Webアプリケーションにリアルタイムなチャット機能を組み込む際、まず第一にサードパーティ製の便利なチャットbotツールが考えられます。ですが、既存システムとのデータ連携などの点から独自にチャットを実装する必要が出てくる場合もあると思います。
今回は、Laravel Broadcastを使用してリアルタイムなチャット機能を簡単に組み込む方法を紹介します。
完成イメージは↓のような感じです。(フロントエンドの実装は省略します)
2. 使用する技術
Laravel Broadcast
Laravel公式サイト(ver10.x)のBroadcast解説はこちら↓。
https://readouble.com/laravel/10.x/ja/broadcasting.html
LaravelのBroadcastは、アプリケーション内で発生したイベントを非同期にブロードキャストするための機能です。これにより、イベントが発生したときに他のユーザーやクライアントに通知することができます。
Broadcastには3種類のチャンネルが存在します。
今回はPublicチャンネルで実装しますが、特定のユーザーのみとのやりとりを実現するのであれば、PrivateまたはPresenceチャンネルでの実装(認証)が必要になります。
Pusher
Pusherは、リアルタイムのWebアプリケーションを構築するためのホステッドサービスです。Pusherを使用すると、ブラウザやモバイルデバイスとの間でリアルタイムのデータ同期を簡単に実現できます。LaravelのBroadcastはPusherをサポートしており、Pusherのアカウントを作成し、キーとシークレットを設定することで、PusherをLaravelプロジェクトで利用できます。
Laravel Echo
Laravel Echoは、クライアントサイドのJavaScriptライブラリであり、リアルタイムのイベント通知を受け取るためのインターフェースを提供します。Laravel Echoは、Pusherやその他のブロードキャストドライバと組み合わせて使用され、クライアントがサーバーからのイベントをリアルタイムに受け取り、反応することができます。Laravel Echoを使用すると、簡単にクライアント側のアプリケーションコードを記述し、リアルタイムな機能を実現できます。
ざっくりとした処理の流れは、以下のような感じです。
3. 実装
セットアップ
Laravelの設定
Broadcastを利用するために、Laravelの設定をしていきます。
config\app.php
// App\Providers\BroadcastServiceProvider::class,
↑のコメントアウトを外します。
.env
BROADCAST_DRIVER=pusher
.envのBroadcast Driverをpusherに設定します。デフォルトではlogになっているはずです。
Pusherの設定
まずはPusherをインストールします。
composer require pusher/pusher-php-server
Pusherのアカウント登録を済ませた後、App Keysに記載されている項目を.envに設定します。
PUSHER_APP_ID=PUSHERのapp_id
PUSHER_APP_KEY=PUSHERのkey
PUSHER_APP_SECRET=PUSHERのsecret
PUSHER_APP_CLUSTER=ap3
Laravel Echoの設定
必要なライブラリをインストールします。
npm install --save laravel-echo pusher-js
resources\js\bootstrap.jsを開いて、echoの設定をします。
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
encrypted: true,
});
イベントの作成
メッセージ送信のイベントをartisanで作成します。
「メッセージが送信された」という意味なので、イベント名はMessageSentにしておきます。
% php artisan make:event MessageSent
Event [app/Events/MessageSent.php] created successfully.
Broadcastingを使用するために、MessageSentクラスでShouldBroadcastを継承します。
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class MessageSent implements ShouldBroadcast
{
以下省略
メッセージ送信
送信するメッセージのオブジェクトとして、App\Library\Message.phpを作成します。
<?php
namespace App\Library;
class Message
{
public $message_id;
public $message;
}
先ほど作成したMessageSentイベントにbroadcastOnメソッドを設定します。
/**
* Get the channels the event should broadcast on.
*/
public function broadcastOn(): Channel
{
return new Channel('testchat');
}
クライアント側でメッセージを送信して、Controllerでイベントをディスパッチします。
$message = new Message;
$message->message_id = $request->message_id;
$message->message = $request->message;
broadcast(new MessageSent($message))->toOthers();
※送信側ではJSでメッセージをレンダリングしている想定なので、toOthersで他者にのみディスパッチしています。
メッセージ受信(イベントリッスン)
window.Echo.channel('testchat').listen('MessageSent', (e) =>
{
console.log(e.message);
// メッセージをレンダリング
});
e.messageの中に受信したメッセージオブジェクトが入っていることを確認できるはずです。あとはJavaScriptでメッセージをレンダリングしてあげれば完成です。
💡Tips
開発中はPusherのログをコンソール出力するように設定した方がやりやすいです。
本番ビルド時は出力しないように設定するのをお忘れなく!
resources\js\bootstrap.js
window.Pusher.logToConsole = true;
4. 機能拡張とカスタマイズ
今回はシンプルなメッセージの送受信のみを実装しましたが、実際のケースではもう少し多機能にする必要があるかもしれません。
以下、追加機能とその実装方法を例示します。
ファイルのアップロード
メッセージ送信と同じ経路を使って実現できます。
例えば、App\Library\Message.phpのプロパティにis_fileフラグやfilenameを追加して、ファイル送信の場合はこのプロパティに該当するデータを送信するようにします。メッセージ送信の際に、storage配下にファイルを保存して、受信側ではこれを参照します。
未読 / 既読の判定
presenceチャンネルを使って簡単に実現できます。
presenceチャンネルの場合、joiningイベント(ユーザーの参加)やleavingイベント(ユーザーの離脱)をリッスンできるので、これを使用して実現します。
~ 省略 ~
.joining((user) => {
// ユーザー参加
})
.leaving((user) => {
// ユーザー離脱
})
~ 省略 ~
💡Tips
PrivateやPresenceチャンネルを利用する際にPusherからリッスンできない場合、認証エラーが考えられます。
BroadcastはデフォルトでLaravelの認証($request->user())を使用しているので、独自に認証を実装している場合は別途、bootstrap.jsに認証のエンドポイントを用意してあげる必要があります。
メッセージ削除
基本的にはメッセージ送信と同じ要領で、メッセージ削除のイベント(MessageDelete)を作成します。
Laravel Echoで削除イベントをリッスンして該当する要素を削除します。
~ 省略 ~
.listen('MessageDeleted', (e) => {
// メッセージ削除
})
~ 省略 ~
5. まとめ
LaravelのBroadcast、Pusher、およびLaravel Echoを使用することで、リアルタイムなチャット機能を簡単に実装することができます。この記事では、セットアップからチャット機能の実装、さらなる拡張までの手順を解説しました。これにより、ユーザー間でのリアルタイムなコミュニケーションを実現する魅力的なアプリケーションを開発することができます。是非、ご自身のLaravelプロジェクトにリアルタイムチャット機能を追加してみてください。