0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Laravel 12 双方向通信

Posted at

Laravel12でWebソケットでのチャットアプリを作成した際の導入方法をメモしました。

1.ブロードキャストとreverbインストール

全てをYESとして必要なnpmライブラリーなどもインストールする

 php artisan install:broadcasting

2. pcntlをインストール

Dockerfileまたはコマンドでpcntlインストールする(今回はDockerfile)

&& docker-php-ext-install pdo pdo_mysql zip bcmath pcntl

3. 6001ポートを外部開放する

今回はdocker-compose.ymlのlaravelのコンテナにポートを追加します。

 ports:
      - 6001:6001

4. 現時点でreverbサーバー(Webソケット専用サーバー)の起動を確認する

エラーが起きていないことを確認する

 php artisan reverb:start --debug 

実装

双方向通信ができることを確認する

5. bladeファイルを作成 views/chat.blade.php

<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8">
   <title>Simple Chat</title>
   <!-- ViteやMixを使っている場合は以下でapp.jsを読み込む -->
   @vite(['resources/js/app.js'])
</head>
<body>
   <h1>Chat Page</h1>

   <!-- メッセージ一覧表示 -->
   <ul id="messages"></ul>

   <!-- メッセージ送信フォーム -->
   <form id="chat-form">
       @csrf
       <input type="text" id="message-input" placeholder="Enter a message...">
       <button type="submit">Send</button>
   </form>

   <script>
       // ページが読み込まれた後に処理
       document.addEventListener('DOMContentLoaded', function() {

           // 1) Echo でメッセージを受信するリスナをセット
           //    ※ bootstrap.js で Echo をインポート済みなので window.Echo が使える
           window.Echo.channel('chat')
               .listen('MessageEvent', (event) => {
                   // event.message を画面に表示
                   const messagesList = document.getElementById('messages');
                   const li = document.createElement('li');
                   li.textContent = event.message;
                   messagesList.appendChild(li);
               });

           // 2) 送信フォームのsubmitハンドラ (POSTでメッセージを送る)
           const chatForm = document.getElementById('chat-form');
           const messageInput = document.getElementById('message-input');

           chatForm.addEventListener('submit', function(e) {
               e.preventDefault();

               // axios は resources/js/bootstrap.js ですでに window.axios として読み込まれている前提
               window.axios.post("{{ route('chat.send') }}", {
                   message: messageInput.value
               })
               .then(response => {
                   // 送信成功 → 入力欄をクリア
                   messageInput.value = '';
               })
               .catch(error => {
                   console.error(error);
               });
           });
       });
   </script>
</body>
</html>

6. イベントクラスを作成

コマンド実行

php artisan make:event MessageEvent

実装

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class MessageEvent implements ShouldBroadcast
{
   use Dispatchable, InteractsWithSockets, SerializesModels;

   public $message; // ←ここを追加
   /**
    * Create a new event instance.
    */
   public function __construct($message)
   {
       $this->message = $message; // ←ここを追加
   }

   /**
    * Get the channels the event should broadcast on.
    *
    * @return array<int, \Illuminate\Broadcasting\Channel>
    */
   public function broadcastOn(): array
   {
       return [
           new Channel('chat'),
       ];
   }
}

7. ルーティングに追加

web.php

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class MessageEvent implements ShouldBroadcast
{
   use Dispatchable, InteractsWithSockets, SerializesModels;

   public $message; // ←ここを追加
   /**
    * Create a new event instance.
    */
   public function __construct($message)
   {
       $this->message = $message; // ←ここを追加
   }

   /**
    * Get the channels the event should broadcast on.
    *
    * @return array<int, \Illuminate\Broadcasting\Channel>
    */
   public function broadcastOn(): array
   {
       return [
           new Channel('chat'),
       ];
   }
}

8. 実際にブラウザを2つ立ち上げて、双方向通信ができているか確認

( リロードなしで両方ともにメッセージが反映されていること)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?