はじめに
前回から間隔が空いてしまいましたが、この記事は人狼GM支援ツールを作る( Vue.js編)の続きとなります。
前回はVue.jsを使ってフロント側を作っていきました。
今回は、この「人狼GM支援ツール」の目玉であるチャット機能を実装します。
さて、今回のチャット機能はLaravel Echo
というLaravelのプラグインを利用していきます。
このLaravel Echo
がどういったものか、どう使うのかについて説明したいと思います。
Laravel Echoの使い方と設定
Laravel Echoとは
Laravel Echoとは……
Laravel EchoはJavaScriptライブラリで、チャンネルの購読とLaravelによるイベントブロードキャストのリッスンを苦労なしに実現してくれます。
だそうです。(日本語ドキュメントより抜粋)
一言で言えば、クライアント側での接続を助けてくれるやつってイメージですね。
npmで管理されているので、導入は以下のコマンドを叩くだけです。
npm install --save laravel-echo
websocketのブロードキャストにはpusherまたはredisが利用できます。
私はredisを利用したので、composerからPredisというライブラリをインストールした上で.envにredisを使うよう設定を追記しました。
websocketサーバの準備
redisを利用する場合には、socket.ioの実装が必要になります。
しかし、頑張って自力で実装する必要はありません。
なぜなら、laravel-echo-server
というLaravel用のsocket.io実装が用意されているからです。
こちらもnpmで管理されているので、以下のコマンドでインストールします。
npm install -g laravel-echo-server
その後、
laravel-echo-server init
で設定ファイルを作成し、
laravel-echo-server start
で起動します。
コンソール上にecho-serverが起動した旨の表示が出れば設定完了です。
以上、Laravelでwebsocketを利用するために必要なモジュールの紹介でした。
細かい設定などは省略しているので、自分で試す際はLaravelの日本語ドキュメントを参考にして進めるとよいでしょう。
redisとチャット機能の仕組み
redisとは
ところで、前の項目で
websocketのブロードキャストにはpusherまたはredisが利用できます。
私はredisを利用したので、composerからPredisというライブラリをインストールした上で.envにredisを使うよう設定を追記しました。
と書きました。
突然出てきたredis
とはなにか、コイツを使うと何が嬉しいのか、という部分から解説していきます。
redisとは、いわゆるNoSQLデータベース(RDBMSでないデータベース)です。
key = value の形のデータをメモリ上に持ち、セッションストアやキャッシュストアなどに使われることが多いです。
今回の用途では、redisのDBとしての機能ではなく、publish/subscribe
の機能を使います。
これは、「別クライアントから送信されたメッセージを受け取る」機能です。
redisに対して、
SUBSCRIBE <チャンネル名>
のコマンドを送ると、redisは受信待ちの状態になります。
この状態で、別のクライアントから
PUBLISH <チャンネル名> <内容>
のコマンドを送ると、SUBSCRIBEしているクライアントにメッセージが届きます。
この機能が、チャット機能のいわば橋渡しのような役割を担います。
Laravelからredisへ
次は、ブラウザ(javascript)から送信した文字がredisに送られるまでの流れを見ていきます。
javascript → Laravelは、Laravelで用意したチャットAPIにajaxで送りました。
送信した文字を受け取ったLaravel側では、「イベントブロードキャスト」
という機能を使います。
簡単に言えば外部連携機能といったところでしょうか。
使い方は単純で、「redisに対してPUBLISHする」というイベントを用意しておくと、発火されたタイミングでredisにPUBLISHを送ります。
これでredisにユーザがブラウザ上で入力したチャット内容が到達しました!
redisからjavascriptへ
redisにPUBLISHしても、肝心のredisがSUBSCRIBEで受信待ちしていなければ意味がありませんね。
そこで、redisの状態からwebsocket接続までをよしなに管理してくれるスゴいヤツ、laravel-echo-server
の出番です。
本来なら自分でNode.jsを書く必要がある、redisの受信待ちや受け取ったメッセージをクライアントまで届けるといった部分を、
一手に担ってくれる優れものです。
laravel-echo-serverは以下のような役割を持ちます
- laravel-echo-serverがredisを受信待ちにして、メッセージを待ち構える。
- 同時に、クライアントとwebsocketの接続を行って、redisがメッセージをSUBSCRIBEしたらその内容をクライアントに流す。
つまり、redisからjavascriptまでの流れを全て担ってくれているわけですね。
これで、あるユーザが入力したチャット内容がLaravelとredis、laravel-echo-serverを介して別のユーザにリアルタイムで伝達されました。
##いったん整理
ここまでの通信の流れを整理してみましょう。
クライアント
↓ HTTP
Webサーバ(Laravel)
↓ PUBLISH
redis
↓ SUBSCRIBE
laravel-echo-server
↓ websocket
クライアント
以上の流れで、私が実装したチャット機能は動いています。
実装とLaravel Mix
Laravel Mix
今まであまりLaravel Echoについて触れてこなかったわけですが、Laravel EchoとはJavaScriptライブラリ
なんですね。
つまり、フロント側に何かしらの手段で読み込ませる必要があるということになります。
ここで、LaravelとJavaScriptの橋渡しとなる最強ライブラリ、Laravel Mix
の出番です。
これはwebpackのラッパーで、煩雑になりがちなビルドやバンドルの設定を少しのJavaScriptとPHPだけで記述できるというものです。
Laravel Echoを使いたい場合、Laravel MixならエントリポイントとなるJavaScriptに以下を記述するだけです。
import Echo from 'laravel-echo';
window.Echo = new Echo({
broadcaster: "socket.io",
host: window.location.hostname + ':6001'
});
laravel-echo-serverを使うためにbroadcaster: "socket.io"
を指定し、
あとはlaravel-echo-serverのドメインを指定するだけで設定完了です。
Echo
というプロパティをwindow
に生やしているので、どこからでもLaravel Echoを呼び出せるようになりました。
Laravel Echoの使い方
前回まで、フロントからサーバ、redis、そしてlaravel-echo-serverへデータが流れるフローを解説しました。
残るはLaravel Echoを使ってlaravel-echo-serverからpushされるデータを受け取るだけです。
早速ですが、実装を見てみましょう。
Echo.channel('werewolves.' + roomId)
.listen('WerewolvesReceived', e => {
store.pushMessageList(e.message)
});
これは実際にフロントで書いたコードの一部となります(「人狼GM支援ツール」の一部なので、人狼だけが見れるチャットの部分ですね)
ブロードキャストするイベント内でどのチャンネルに飛ばすか
を指定しているので、受け取る側では指定したチャンネルからどのイベントをリッスンするか
を指定します。
laravel-echo-serverとブラウザはwebsocketで接続しているので、あとは受け取ったメッセージを画面に表示させるだけです。
駆け足気味な説明でしたが、ついにチャット機能が完成しました!
まとめ
今回はLaravel Echoでチャット機能を作ったお話でした。
「人狼GM支援ツールを作る」はこれで終わりとする予定ですが、また何かネタを思い出したら書くかもしれません。
ここまで読んでいただきまして、ありがとうございました。