今回はリアルタイムチャット機能を作っていきます。
続き(編集と削除)
pusherとlaravel echoを使います。laravel7.xです。
目次
- 大まかな流れ
- 必要なモデル、コントローラーの作成
- routeの設定
- メッセージ保存
- メッセージの表示
- pusher登録
- 環境変数設定
- laravel-echoとpusherのインストール
- 通知イベントを作成
- vue、controllerに記述追加
すべて表示
大まかな流れ
1, 必要なモデル、コントローラーの作成
2, メッセージ保存
3, メッセージの表示
4, pusher登録
5, 環境変数設定
6, laravel-echoとpusherのインストール
7, 通知イベントを作成
8, vueに記述追加
9, 確認
って感じで実装しています。
必要なモデル、コントローラーの作成
まずはモデルとマイグレーションファイルの作成から入ります。コマンドはターミナルで以下のような感じでしょう。
php artisan make:model Message -m
マイグレーション ファイルには、以下のような形で。今回はそこまで長い文章を送らない想定なのでstringで型指定してしてますが、textとかでも良いかと。
外部キーはlaravel7から新しい書き方もできるようになっています。
$table->string('text');
$table->foreignId('user_id')->constrained(); 外部キーつけるなら。
laravel7から上記の1行で下記の2行を表すことが出来る。
// $table->unsignedBigInteger('user_id');
// $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
上記が済んだらターミナルでphp artisan migrate実行です。
次はモデルファイルにfillableの記述を書きます。アソシエーションも。
Messageモデル
protected $fillable = ['text', 'user_id'];
public function user()
{
return $this->belongsTo('App\User');
}
Userモデル
public function messages()
{
return $this->hasMany('App\Message');
}
上記のように書ければアソシエーションもおっけいです。
routeの設定
Route::resource('room.message', 'MessageController');
メッセージ保存
まずはvue側から
<div v-for="message in array" :key="message.id">
<div class="media-body ml-3">
<div class="bg-light rounded py-2 px-3 mb-2">
<p class="text-small mb-0 text-dark">{{message.text}}</p>
</div>
</div>
<form enctype="multipart/form-data" @submit.prevent="send" class="bg-light">
<div class="input-group">
<input type="text" placeholder="Type a message" aria-describedby="button-addon2" class="form-control rounded-0 border-0 py-4 bg-light" v-model="text">
<div class="input-group-append">
<button id="button-addon2" type="submit" class="btn btn-link"><font-awesome-icon icon="coffee" /></button>
</div>
</div>
</form>
省略。。
data() {
return {
text: '',
array: [],
}
},
省略。。。
getMessages() {
axios.get(任意のpath_link).then(res => {
// propsで渡されたmessagesをarrayに入れている
this.array = res.data
})
},
send() {
let obj = {
text: this.text
}
axios.post(任意のpath, obj).then(res => {
this.getMessages()
}).catch(function(error){
console.log(error)
})
},
axiosで入力された文字を飛ばしています。
public function store(Request $request)
{
$user = Auth::user();
$message = new Message();
$message->text = $request->text;
$message->user_id = $user->id;
$message->save();
return $message;
}
ここまででデータベースにメッセージ保存されることが確認できればオーケー!
メッセージの表示
メッセージの表示についてはgetMesagesメソッドを呼び出して値をarrayに入れて、v-forで表示させているイメージです。axios.getはindexに飛ばしてます。
public function index()
{
$messages = Message::get();
return $messages;
}
pusher登録
pusherにログイン(新規登録)をしてapi keyを使います。
この記事を参考に進めています。pusherについても同様です。
環境変数設定
.envの環境変数のところにpusherで取得した値を設定していきます。
BROADCAST_DRIVER=pusher pusherに変更する。元々はlogのはず
以下それぞれpusherのものを設定していく。
PUSHER_APP_ID=******
PUSHER_APP_KEY=********************
PUSHER_APP_SECRET=********************
PUSHER_APP_CLUSTER=***
環境変数の設定後は下記コマンドを忘れずに。
php artisan config:cache
config/app.php内のBroadcastServiceProviderをコメントアウトを外す。
// App\Providers\BroadcastServiceProvider::class,
変更後
App\Providers\BroadcastServiceProvider::class,
laravel-echoとpusherのインストール
をインストール。ターミナルでの作業です。2回ある。
composer require pusher/pusher-php-server "~3.0"
npm install --save laravel-echo pusher-js
インストールが完了したら、resources/js/bootstrap.jsの記述で以下をコメントインする。
import Echo from 'laravel-echo'
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
encrypted: true
});
通知イベントを作成
php artisan make:event MessageCreated でイベント作成
作成されたファイルを少し書き換えます。
#1, ShouldBroadcastの追加
#2, public宣言
#3, broadcastOn()でchatチャンネルを作成。
class MessageCreated implements ShouldBroadcast #1
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message; #2
/**
* Create a new event instance.
*
* @return void
*/
public function __construct(Message $message)
{
return $this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('chat');
}
}
vue、controllerに記述追加
メッセージが保存された際にMessageCreatedが発火するように。pusherにいきます。pusherのdebug consoleでみれます。
$message->save();
event(new MessageCreated($message));
vue側はライフサイクルメソッドのmountedに記載を追加。コントローラーで設定したMessageCreatedが動くのをlistenで検知して動いたらthis.getMessages()を実行するようにしている。
mounted() {
this.getMessages() メッセージ全取得
pusherからのデータを受け取る
Echo.channel('chat').listen('MessageCreated', (e) => {
this.getMessages()
})
},
確認
ここまで行けたらメッセージの送信はリアルタイムで出来ます。pusherでもdebug consoleで中身の送信が確認できます。
もしうまくいっていない場合はconsole.logなどを使って処理がどこまで動いているか確認していきましょう。
ポイント
正しくメッセージが保存できる。
コントローラーで保存が完了した時にMessageCreatedが発火するか。pusherに渡ってたらおっけい。
mounted()からechoで処理の呼び出しに成功するか。console.logで確認できる。
まとめ
初めてlaravel echoとpusherを使ったけどそこまで難しくないので、このまま次はmessageの編集と削除についての記事も書いていきたい。
そんな感じで今回は
以上!