Laravel 广播
安装
服务端
付费方案
- Pusher Channels
- Ably
这里不作介绍
开源方案
- laravel-websockets
安装请移步 https://www.cuiwei.net/p/1659113677
- Soketi
安装请移步 https://www.cuiwei.net/p/1093836635
- Laravel Reverb - Laravel 第一方可扩展的 WebSocket 服务器
安装请移步 https://www.cuiwei.net/p/1502119488
前端
安装 laravel-echo
npm install --save-dev laravel-echo pusher-js
以私人频道为例
场景如下:用户支付完成,前端需要从后端获取支付结果,并展示给用户
基本流程
后端
- 配置
- 注册
BroadcastServiceProvider
- 创建广播事件,设置私人频道
orders.{order_id}
- 在
routes/channels.php
完成频道授权 - 触发广播事件
OrderStatusUpdatedEvent::dispatch($order);
前端
- 实例化了 Laravel Echo
- 监听
orders.{order_id}
频道
后端
配置
安装Pusher SDK
composer require pusher/pusher-php-server
配置文件 config/broadcasting.php
,一般是在.env
文件中修改
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=12345
PUSHER_APP_KEY=ABCDEFG
PUSHER_APP_SECRET=HIJKLMNOP
PUSHER_HOST=docker-laravel-websockets
PUSHER_PORT=6001
PUSHER_SCHEME=http
PUSHER_APP_CLUSTER=mt1
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_HOST="laravel2.cw.net"
VITE_PUSHER_PORT="${PUSHER_PORT}"
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
::: 提示 当使用Laravel WebSockets作为Pumper替换时,之前没有使用过Puscher,您设置什么作为PUSHER_变量并不重要。只要确保它们对每个项目都是独一无二的。 :::
注册BroadcastServiceProvider
在广播任何事件之前,您首先需要注册 App\Providers\BroadcastServiceProvider
。在新的 Laravel
应用程序中,您只需在 config/app.php
配置文件的 providers
数组中取消注释此提供程序。这个 BroadcastServiceProvider
包含注册广播授权路由和回调所需的代码。
创建广播事件
php artisan make:event OrderStatusUpdatedEvent
#修改一下
class OrderStatusUpdatedEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public Order $order;
public function __construct(Order $order)
{
$this->order=$order;
}
public function broadcastOn()
{
//Channel代表任何用户都可以订阅的公共频道
return new Channel('orders.'.$this->order->id);
//PrivateChannel, PresenceChannel 代表需要 频道授权 的私人频道
return new PrivateChannel('orders.'.$this->order->id);
return new PresenceChannel('orders.'.$this->order->id);
}
}
授权频道
请记住,用户必须获得授权才能在私人频道上收听。我们可以在应用程序的 routes/channels.php
文件中定义我们的频道授权规则。在此示例中,我们需要验证任何尝试在私有 orders.1
频道上收听的用户实际上是订单的创建者:
use App\Models\Order;
Broadcast::channel('orders.{id}', function ($user, string $order_id) {
// return true;
\Illuminate\Support\Facades\Log::info($user);
return $user->id === Order::findOrNew($order_id)->user_id;
});
触发广播事件OrderStatusUpdatedEvent::dispatch($order);
Auth::loginUsingId(1, true);
$order = \App\Models\Order::query()->first();
OrderStatusUpdatedEvent::dispatch($order);
如果只是调试一下,也可以用tinker
#启动 Laravel 的交互式解释器
php artisan tinker
#执行
event (new \App\Events\NewTrade('test'))
前端
实例化 Laravel Echo
安装 Echo
后,您就可以在应用程序的 JavaScript
中创建一个新的 Echo
实例了。一个很好的地方是在 Laravel 框架中包含的 resources/js/bootstrap.js
文件的底部。默认情况下,此文件中已包含一个示例 Echo
配置 - 您只需取消注释即可:
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER ?? 'mt1',
wsHost: import.meta.env.VITE_PUSHER_HOST ? import.meta.env.VITE_PUSHER_HOST : `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});
监听orders.{order_id}频道
我选择在项目入口页添加
vi resources/views/welcome.blade.php
@vite('resources/js/app.js')
<script>
window.onload = function(){
Echo.private(`orders.1`)
.listen('OrderStatusUpdatedEvent', (e) => {
console.log('privite:')
console.log(e.order);
});
// Echo.channel(`orders.1`)
// .listen('OrderStatusUpdatedEvent', (e) => {
// console.log(e.order);
// });
};
</script>
</head>
测试一下
启动 websockets 服务
php artisan websockets:serve
运行 Vite
Laravel9 不再推荐Mix,而是推荐Vite
# 运行 Vite 开发服务器...
npm run dev
# 构建并为生产环境版本化资产...
npm run build
Vite开发服务器,为您的Laravel应用程序提供热更新。默认使用5173端口,访问http://localhost:5173/
,就一个普通页面,看看就行了。和你的项目路由没有关系
这个开发服务器将自动检测您文件的改变并在任何打开的浏览器窗口中立即反映它们。
1、注意:运行dev 会改变js的引入方式
正常是这样的
运行dev 后
2、注意:引入websockets后,运行dev后,控制台日志也会有变化
正常是看不到[vite] connecting...
、[vite] connected.
这种日志
运行dev 后,在浏览器控制台会看到
最后
先访问项目首页http://laravel2.cw.net
,并打开 浏览器控制台
然后,执行命令触发广播事件
root@php-fpm:/var/www/laravel-demo2# php artisan order:update
这时你应该可以看到输出:
参考
https://learnku.com/docs/laravel/9.x/broadcasting/12223#client-side-installation