$ php artisan –version
Laravel Framework 8.46.0
$ composer require pusher/pusher-php-server
$ php artisan make:model Message -m
migrationfile
public function up() { Schema::create('messages', function (Blueprint $table) { $table->bigIncrements('id'); $table->integer('sent_id')->index()->unsigned(); $table->integer('recived_id')->index()->unsigned(); $table->text('message'); $table->timestamps(); }); }
model(Message.php)
protected $fillable = [ 'sent_id', 'recieved_id', 'message', ];
$ php artisan serve –host 192.168.33.10 –port 8000
register画面からuserを3つぐらい作ります。
$ php artisan make:controller HomeController
route
use App\Http\Controllers\HomeController; Route::get('/home', [HomeController::class, 'index']);
HomeController.php
use App\Models\User; use Illuminate\Support\Facades\Auth; class HomeController extends Controller { // public function __construct(){ $this->middleware('auth'); } public function index(){ $user = Auth::user(); $users = User::where('id','<>', $user->id)->get(); return view('chat.user_select', compact('users')); } }
layout/app.blade.php
L bootstrap5を追加
L pusher.jsを追加
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous"> // 省略 <main> @yield('content') </main> // 省略 <script src="https://js.pusher.com/7.0.3/pusher.min.js"></script> <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> @yield('script')
user_select.blade.php
@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> </div> </div> <table class="table"> <thead> <tr> <th>#</th> <ht>Name</ht> <th></th> </tr> </thead> <tbody> @foreach($users as $key => $user) <tr> <td>{{$loop->iteration}}</td> <td>{{$user->name}}</td> <td><a href="/chat/{{$user->id}}"><button type="button" class="btn btn-primary">Chat</button></a></td> </tr> </tbody> </table> </div> @endsection
$ php artisan make:controller ChatController
route
use App\Http\Controllers\ChatController; Route::get('/chat/{recieved_id}', [ChatController::class, 'index'])->name('chat'); Route::post('/chat/send', [ChatController::class, 'store'])->name('chatSend');
chat/chat.blade.php
@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> </div> </div> <!-- チャットルーム --> <div id="room"> @foreach($messages as $key => $message) @if($message->sent_id == \Illuminate\Support\Facades\Auth::id()) <div class="send" style="text-align: right"> <p>{{$message->message}}</p> </div> @endif @if($message->received_id == \Illuminate\Support\Facades\Auth::id()) <div class="send" style="text-align: right"> <p>{{$message->message}}</p> </div> @endif @endforeach </div> <form> <textarea name="message" style="width:100%"></textarea> <button type="button" id="btn_send" class="btn btn-primary">送信</button> </form> <input type="hidden" name="sent_id" value="{{$param['sent_id']}}"> <input type="hidden" name="recieved_id" value="{{$param['recieved_id']}}"> <input type="hidden" name="login" value="{{\Illuminate\Support\Facades\Auth::id()}}"> </div> @endsection @section('script') <script> Pusher.logToConsole = true; var pusher = new Pusher('*', { cluster: '*', encrypted: true }); var pusherChannel = pusher.subscribe('testApp'); pusherChannel.bind('chat_event', function(data){ let appendText; let login = $('input[name="login"]').val(); if(data.sent_id === login){ appendText = '<div class="send" style="text-align:right"><p>' + data.message + '</p></div> '; } else if(data.recieved_id === login){ appendText = '<div class="recieve" style="text-align:left"><p>' + data.message + '</p></div> '; } else { return false; } $("#room").append(appendText); if(data.recieved_id === login){ Push.creaet("新着メッセージ", { body: data.message, timeout: 8000, onClick: function(){ window.focus(); this.close(); } }) } }); $.ajaxSetup({ headers : { 'X-CSRF-TOKEN' : $('meta[name="csrf-token').attr('content'), } }); $('#btn_send').on('click', function(){ $.ajax({ type: 'POST', url: '/chat/send', data: { message : $('textarea[name="message"]').val(), sent_id : $('input[name="sent_id"]').val(), recieved_id : $('input[name="recieved_id"]').val(), } }).done(function(result){ $('textarea[name="message"]').val(''); }).fail(function(result){ }); }); </script> @endsection
$ php artisan make:event ChatMessageRecieved
ChatMessageRecieved.php
public function __construct($request) { // $this->request = $request; } /** * Get the channels the event should broadcast on. * * @return \Illuminate\Broadcasting\Channel|array */ public function broadcastOn() { return new PrivateChannel('testApp'); } public function broadcastWith(){ return [ 'message' => $this->request['message'], 'sent_id' => $this->request['sent_id'], 'recieved_id' => $this->request['recieved_id'], ]; } public function broadcastAs(){ return 'chat_event'; }
あ、想定通りに動いてないけど、ちょっと思い出してきた。
pusherは基本jsでonclickでpostしてstoreし、eventを発火させて新しいデータを取得するんだった。
でも確かpusherのcrudentialは.envだった記憶があるんだが。。。