后端
1、安装扩展
composer require beyondcode/laravel-websockets
发布迁移
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"
php artisan migrate
发布配置
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"
配置 .env
PUSHER_APP_ID=
PUSHER_APP_KEY=your-pusher-key
PUSHER_APP_SECRET=
PUSHER_HOST=127.0.0.1
PUSHER_PORT=6001
PUSHER_SCHEME=http
PUSHER_APP_CLUSTER=mt1
2、确保 config/app.php
文件,providers
配置中没有注释依赖项。如果有不能解释的报错,可以确认一下。
3、创建事件
php artisan make:event DemoEvent
修改类 App\Events\DemoEvent
,注意添加实现 ShouldBroadcast
。
<?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 DemoEvent implements ShouldBroadcast # 添加实现类
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public string $message;
// 使用成员变量,前端 listen 事件名为 `DemoEvent`
// public $broadcastAs = 'DemoEvent';
public function __construct()
{
$this->message = 'Hello friend';
}
// 使用成员方法,前端 listen 事件名为 `.DemoEvent`
public function broadcastAs() {
return 'DemoEvent';
}
public function broadcastOn()
{
// PrivateChannel 需要登录,改为 Channel
// channel 名称本文改为 public
return new Channel('public');
}
}
如果不指定 broadcastAs,默认事件名为类名,即:
App\Events\DemoEvent
4、运行服务
php81 artisan websockets:serve
5、调用/下发事件
# 以下都行
DemoEvent::dispatch();
broadcast(new DemoEvent())->toOthers();
broadcast(new DemoEvent());
event(new DemoEvent());
6、DASHBOARD
访问 /laravel-websockets
可以打开 dashboard 和调试,地址可以在 config/websockets.php
中配置
前端
1、以 vue 为例,安装扩展
npm i -D laravel-echo pusher-js
2、添加 laravel-echo.js
文件
import Echo from "laravel-echo";
import Pusher from "pusher-js";
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: "pusher",
key: "your-pusher-key",
wsHost: window.location.hostname,
wsPort: 6001,
forceTLS: false,
disableStats: true,
cluster: "mt1",
});
在 main.js
中引入
import "./laravel-echo";
3、在合适的位置订阅消息
window.Echo.channel("public").listen(".DemoEvent", (e) => {
console.log(e.message);
});
此处
DemoEvent
为事件名,在后端可以通过 broadcastAs 来指定:
- 如果没有指定,默认为类名:
App\\Events\\DemoEvent
- 如果使用成员变量:
DemoEvent
- 如果使用成员方法:
.DemoEvent
私有通道
后端
1、修改 BroadcastServiceProvider.php
文件
// Broadcast::routes(); // 注释这行
Broadcast::routes(['middleware' => ['auth:sanctum']]); // 增加这行
2、在 routes/channels.php
中,添加通道验证
Broadcast::channel('private.{id}', function($user, $id){
return true; // 仅测试
});
3、创建新的事件类
php artisan make:event PrivateEvent
修改类 App\Events\PrivateEvent
<?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 PrivateEvent implements ShouldBroadcast # 添加实现类
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public string $message;
public function __construct()
{
$this->message = 'Hello friend';
}
// 使用成员方法,前端 listen 事件名为 `.PrivateEvent`
public function broadcastAs() {
return 'PrivateEvent';
}
public function broadcastOn()
{
// 名称通常需要带用户ID用于验证,本文设为 private.1
return new PrivateChannel('private.1');
}
}
前端
1、修改 laravel-echo.js
文件
import Echo from "laravel-echo";
import Pusher from "pusher-js";
window.Pusher = Pusher;
// 获取token
const token = '123'
window.Echo = new Echo({
broadcaster: "pusher",
key: "your-pusher-key",
wsHost: window.location.hostname,
wsPort: 6001,
forceTLS: false,
disableStats: true,
cluster: "mt1",
auth: { // 增加这部分
headers: {
Authorization: `Bearer ${token}`,
},
},
});
2、在合适的位置订阅消息
window.Echo.private("private.1").listen(".PrivateEvent", (e) => {
console.log(e.message);
});
参考:
- https://learnku.com/docs/laravel/10.x/broadcasting/14860
- http://kailian.github.io/2019/04/14/laravel-broadcast
- https://learnku.com/articles/17327
- https://beyondco.de/docs/laravel-websockets/getting-started/installation
- https://learnku.com/articles/64710
- https://tchury.substack.com/p/add-websockets-to-laravel-in-10-mins-4f20c12001ab
- https://github.com/laravel/echo/issues/26#issuecomment-248178873
- https://stackoverflow.com/questions/54229753/getting-403-error-when-using-private-channels-with-laravel-broadcast
- https://laracasts.com/discuss/channels/laravel/using-private-channels-on-laravel-echo