この記事はWHITEPLUSのカレンダー | Advent Calendar 2018 - Qiitaの23日目になります。
どうも皆さん、おはこんばんにちは。WHITEPLUSのエンジニアのkazunkrandsです。 昨日に引き続き、どうもです。
私は、弊社で新規事業として運営している生活サービスに特化した事業者様とユーザーのマッチングプラットフォームである生活手帖というサービスのシステム担当をしております。 ※ここまでのクダリは昨日の内容と同じでございます。
生活手帖には生活サービスを提供する側の事業者様と、サービスを受けるユーザーとのやりとりを行うためのメッセージ機能が存在します。現状、いずれか一方の新着メッセージを送信した際にはメールにて相手に通知される仕組みになっております。ただ、ページ上にリアルタイムに「メッセージが来たよ〜」といった通知が見れたら、メッセージのレスポンス時間短縮にも繋がるし便利じゃないかな〜と思ったのが本記事を書くきっかけとなりました。
開発環境
今回も、弊社で普及しているWebフレームワークのLaravelで簡単な通知アプリケーションを作成したいと思います。 環境は以下のような感じです。
- Laravel 5.5系
- PHP7.1系
Pusherの導入
Pusherは、WebSocketを利用したリアルタイム双方向通信を行うためのAPIです。Webだけでなく、iOS・Androidアプリにも対応しています。
Pusherプロジェクト作成(Sign Up)
上のPusherの公式ページよりログインアカウントを作成します。GithubアカウントやGoogleアカウントからも作成できます。
ログインすると、以下のようなポップが出ます。
今回はfront-endは「JQuery」、back-endは「Laravel」を選択しました。
プロジェクトが作成されるとOverviewタブの左下にKeys情報が表示されます(後々必要になる)。
Pusherライブラリインストール
ComposerでPusherライブラリをインストールします。
composer require pusher/pusher-php-server
config下準備
今回は、Laravelのイベントブロードキャストを使用してリアルタイム通信を実現します。
config/app.php
で以下のApp\Providers\BroadcastServiceProvider::class
の行のコメントアウトを解除します。
/* * Application Service Providers... */ App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, App\Providers\BroadcastServiceProvider::class, // ←ここ App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class,
※これしないと、イベントが全く走りません。当たり前ではあるのですが、凡ミスしてここに気づかず私は30minほどハマりました・・・。
config/web.php
の末尾に以下を追加します。
Route::get('/hello', function() { event(new \App\Events\HelloPusher('テストメッセージ')); return 'hello pusher'; });
config/broadcasting.php
の以下のところをenvで設定できるよう修正します。clusterを正しく設定しないと動かないです。
'pusher' => [ 'driver' => 'pusher', 'key' => env('PUSHER_APP_KEY'), 'secret' => env('PUSHER_APP_SECRET'), 'app_id' => env('PUSHER_APP_ID'), 'options' => [ 'cluster' => env('PUSHER_APP_CLUSTER'), // ←ここ 'encrypted' => true, ], ],
.env
を以下のように修正します。PUSHER_APP_CLUSTER
はexampleにもともと入っていない定義なので追加してください。
PUSHER_APP_ID=XXXXXX PUSHER_APP_KEY=XXXXXXXXXXXXXXXXX PUSHER_APP_SECRET=XXXXXXXXXXXXXXXXX PUSHER_APP_CLUSTER=XXX
イベント作成
以下のコマンドでイベントクラスを生成します。とりあえずクラス名はHelloPusher
としました。
php artisan make:event HelloPusher
app/Events
配下にクラスが生成されるため、以下のように編集します。
<?php namespace App\Events; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; class HelloPusher implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; public $message; /** * コンストラクタ * * @param string $message */ public function __construct($message = 'hello pusher') { $this->message = $message; } /** * 送信先のチャンネル * @return array */ public function broadcastOn() { return ['my-channel']; } /** * イベント名 * @return string */ public function broadcastAs() { return 'my-event'; } }
View
Viewは新しく生成しても良かったのですが、今回は横着にwelcomeを編集しちゃいました。簡単に説明すると、前項で作成したイベントを画面上で待機し、イベントを受信すると画面右端からニョロッと通知が出ます。通知に関してはjqueryのnotify.jsプラグインを使いました。
<!DOCTYPE html> <head> <title>Pusher Test</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/notify/0.4.2/notify.min.js"></script> <script src="https://js.pusher.com/4.3/pusher.min.js"></script> <script> // log出力設定(本番環境とかでは消してね) Pusher.logToConsole = true; // XXXXにApp Keyを入れてね。XXXにclusterを入れてね。 var pusher = new Pusher('XXXX', { cluster: 'XXX', forceTLS: true }); var channel = pusher.subscribe('my-channel'); channel.bind('my-event', function(data) { $.notify(data.message, 'info'); }); </script> </head> <body> <h1>Pusher Test</h1> <p> 別ブラウザ(タブ)で/helloにアクセスすると、右端から通知が出現します。 </p> </body>
完成品
localhostで/
を開くと、イベント受信待ちとなります。ここで、別ブラウザ(タブ)で/hello
にアクセスすると/
の方に以下のように通知が表示されます。
シンプルですが、これだけです(笑)。
まとめ
Pusherを使うことで容易にリアルタイム通信が実現できます。実を言うと、生活手帖のメッセージ機能自体もこのPusherを利用してたりします。チャット形式でお客様と事業者様間のメッセージのやりとりを実現しております。
ただ前述の通り、config系でコメントアウトの罠にまんまとハマってしまってしまい予想以上に時間を要してしまいました(汗)。
参考
- laravel5.3でwebsocket通信のチュートリアル(Pusher) #PHP - Qiita
http://tech.innovation.co.jp/2016/08/19/laravel-with-pusher.html
最後に
明日は、私と同じくエンジニアngmyさんの「リネットのPHP + LaravelアプリケーションのCIにPHPStanによる静的解析を導入した話」です。
そして、WHITEPLUSでは一緒に働く仲間を募集しています。募集ポジションはこちら