laravel
チャット
readouble.com
ブロードキャスト

【メモ】Laravelのブロードキャストについて公式で分かりづらかった部分があったので補足

Laravel-Echoでチャット機能を作ろうとしていてLaravel公式のサイトを見たのだが、ブロードキャストのプレゼンスチャンネルの部分で分かりづらい部分あったので補足

(参考)
https://readouble.com/laravel/5.4/ja/broadcasting.html

(1)プレゼンスチャンネルへの参加

(チャットルームへの参加)

Echo.join('chat.' + roomId)
    .here((users) => {
        //
    })
    .joining((user) => {
        console.log(user.name);
    })
    .leaving((user) => {
        console.log(user.name);
    });

JSファイルに記述。
1行目のroomIdってどこから来た??って思ってたけど、
このroomIdは別途同じJSファイル内で定義しないとダメっぽい。

(2)プレゼンスチャンネルの許可

(チャットルームへの入室の許可)

Broadcast::channel('chat.{roomId}', function ($user, $roomId) {
    if ($user->canJoinRoom($roomId)) {
        return ['id' => $user->id, 'name' => $user->name];
    }
});

これは、(1)のプレゼンスチャンネルに参加する際に参加していいですよ、という認可を与えるための記述。routes/channels.phpに記載。
1行目の{roomId}$roomIdってどこから来た??って思った。
{roomId}は(1)で定義したroomIdが入り、{roomId}に入ってきた値が$roomIdに渡されるっぽい。

(3)プレゼンスチャンネルへのブロードキャスト

(チャットルームへのメッセージの投稿)

namespace App\Events;

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

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

    /**
     * Message
     *
     * @var Message
     */
    public $message;

    /**
     * User
     *
     * @var User
     */    
    public $user;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Message $message,User $user)
    {
        //
        $this->message = $message;
        $this->user = $user;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return new PresenceChannel('chatroom.'.$this->message->room_id);
    }
}

これは、ShouldBroadcastインターフェースを実装したイベントクラスに記述。
このイベントクラスをどこで呼び出すかというと、例えば投稿ボタンをクリックした後に非同期でメッセージの中身をDBに保存する処理の中で呼び出す。
例えばこんな感じ。

$user = Auth::user();

$message = new App\Eloquent\Message();
$message->message = request('message');
$message->room_id = request('roomId');
$user->messages()->save($message);

// ここがイベントの呼び出し部分
broadcast(new MessagePosted($message,$user))->toOthers();

(1)(2)がページ表示時(入室時)、(3)(4)はメッセージ投稿時に関係してくる感じ?

以上。