28. Laravel 内置聊天室

Laravel 内置聊天室

配套视频地址:https://www.bilibili.com/video/av80196918

配置

  1. 打开 config/app.php 中 BroadcastServiceProvider 注释,即注册广播授权路由。
  2. 在 .env 中配置驱动 BROADCAST_DRIVER=redis
  3. 在 .env 中配置数据库
  4. 取消 config/database.php 中的 redis 前缀
'redis' => [
    'options' => [
        'prefix' => '',
    ],
];

安装服务

打开命令行,cd 到项目根目录下

npm install --save socket.io-client |  echo 'websocket 客户端'
npm install --save laravel-echo     |  echo 'websocket 客户端封装'
npm install -g laravel-echo-server  |  echo 'websocket 服务端'
npm install                         |  echo '安装所有其他依赖'
npm run watch                        |  echo '监控文件变化编译前端资源'
laravel-echo-server init             |  echo '初始化 websocket 服务端'
laravel-echo-server start            |  echo '启动 websocket 服务端'

初始化 websocket 客户端

在 resources/js/bootstrap.js 中添加以下代码

import Echo from "laravel-echo"

window.io = require('socket.io-client');

window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname + ':6001'
});

创建聊天室

Route::get('/login/user/{id}', fn($id) => auth()->loginUsingId($id));

Route::get('/room/{roomId}', function ($roomId) {
    broadcast(new \App\Events\Hello($roomId));
    return view('welcome', ['roomId' => $roomId]);
});

安装聊天室客户端

window.Echo.join(`chat.${roomId}`)
    .here((users) => {
        console.log(users);
    })
    .joining((user) => {
        console.log(user.name + ' 来了');
    })
    .leaving((user) => {
        console.log(user.name + ' 走了');
    });

安装频道认证路由

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

定义聊天室事件

<?php

namespace App\Events;

use App\User;
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 Hello implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

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

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PresenceChannel('room.'.$this->roomId);
    }
}

开启聊天模式

监听聊天事件

window.Echo.join(`chat.${roomId}`)
    .here((users) => {
        console.log(users);
    })
    .joining((user) => {
        console.log(user.name + ' 来了');
    })
    .leaving((user) => {
        console.log(user.name + ' 走了');
    })
    .listen('NewMessage', (e) => {
        console.log(e.user.name + ":" + e.msg);
    });

定义聊天室群聊事件

<?php

namespace App\Events;

use App\User;
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;
use Illuminate\Support\Facades\Log;

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

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

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PresenceChannel('chat.'.$this->roomId);
    }
}

安装聊天室群聊客户端

<!doctype html>
<html lang="en">
<head>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <script>
        var roomId = "{{ $roomId }}";
    </script>
    <script src="/js/app.js"></script>
</head>
<body>
    <input type="text" id="msg">
    <button onclick="axios.get('/room/{{ $roomId }}/'+document.getElementById('msg').value)">发送</button>
</body>
</html>

定义聊天室群聊路由

Route::get('/room/{roomId}/{msg}', function ($roomId, $msg) {
    broadcast(new \App\Events\NewMessage($roomId, $msg))->toOthers();
});

posted on   何苦->  阅读(148)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示