laravel9.x + beyondcode/laravel-websockets 实现广播 + websocket
beyondcode/laravel-websockets 文档
安装 beyondcode/laravel-websockets
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"
安装 pusher-php-server
composer require pusher/pusher-php-server:7.0.2
修改.env文件
BROADCAST_DRIVER=pusher
# 这里PUSHER_APP_ID、PUSHER_APP_KEY、PUSHER_APP_SECRET随便填写
PUSHER_APP_ID=test-websockets
PUSHER_APP_KEY=qwerty
PUSHER_APP_SECRET=123456789
PUSHER_HOST=localhost
PUSHER_PORT=6001
PUSHER_SCHEME=http
PUSHER_APP_CLUSTER=mt1
启动websockets
# 默认启动
php artisan websockets:serve
# 指定端口
php artisan websockets:serve --port=3030
# 指定host
php artisan websockets:serve --host=127.0.0.1
结合supervisord管理
安装客户端
npm install --save-dev laravel-echo pusher-js
npm run dev
修改 resources/js/bootstrap.js文件
// 打开注释
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,
wsHost: 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'],
});
增加一条web路由
Route::get('/', function () {
return view('welcome');
});
// 发送广播
Route::get('/event', function () {
$str = \Illuminate\Support\Str::random();
broadcast(new \App\Events\Free($str));
});
welcome.blade.php文件新增
// 引入app.js文件
@vite('resources/js/app.js')
<script>
// document.addEventListener 防止提示Echo未定义
document.addEventListener("DOMContentLoaded", function (event) {
Echo.channel(`channel-free`)
.listen('Free', (e) => {
console.log('listen ok')
console.log(e.data);
});
})
</script>
Free Event 文件
<?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 Free implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $msg;
public function __construct($msg)
{
$this->msg = $msg;
}
public function broadcastOn()
{
return new Channel('channel-free');
}
public function broadcastWith ()
{
return [
'data' => $this->msg
];
}
}
自定义WebSocket处理程序
创建
MyCustomWebSocketHandler.php
文件<?php namespace App; use Illuminate\Support\Facades\Log; use Ratchet\ConnectionInterface; use Ratchet\RFC6455\Messaging\MessageInterface; use Ratchet\WebSocket\MessageComponentInterface; class MyCustomWebSocketHandler implements MessageComponentInterface { public function onOpen(ConnectionInterface $connection){ // 这里处理 返回的Error Exception thrown undefined property Ratchet\Server\IoConnection::$app错误 $socketId = sprintf('%d.%d', random_int(1, 1000000000), random_int(1, 1000000000)); $connection->socketId = $socketId; $connection->app = new \stdClass(); $connection->app->id = env('APP_NAME').'- Test'; return $connection->send('您已链接:'.now()->toDateString()); } public function onClose(ConnectionInterface $connection) { } public function onError(ConnectionInterface $connection, \Exception $e) { } public function onMessage(ConnectionInterface $connection, MessageInterface $msg) { // 接受客户端发送过来的信息 Log::info($msg); return $connection->send($msg); } }
web.php
新增一条路由\BeyondCode\LaravelWebSockets\Facades\WebSocketsRouter::webSocket('/my-websocket', \App\MyCustomWebSocketHandler::class);
客户端监听
ws://127.0.0.1:6001/my-websocket
beyondcode/laravel-websockets 自带了一个 Debug Dashboard
备注
1.在监听私有频道时,如果auth guard 为其它时,channels.php
Broadcast::channel('get-device-info.{id}', function ($user, $id) {
// 验证当前登录的用户id是否等于他监听的私有频道的id
return (int) $user->id === (int) $id;
}, ['guards' => ['wechat_user']]);
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: