首页 » 排名链接 » Laravel+Uniapp项目中使用广播系统(广播机制终端对象连接)

Laravel+Uniapp项目中使用广播系统(广播机制终端对象连接)

神尊大人 2024-10-24 17:35:29 0

扫一扫用手机浏览

文章目录 [+]

Laravel通过Broadcasting可以使用如今时下很热的Websocket技术。
Broadcasting允许你在服务端代码和客户端 JavaScript 应用之间共享相同的事件名。

环境参数Redis 7.0.0PHP8.0Laravel 8.5广播架构

查阅目前有多种种广播机制可供选择:我们使用 Redis + socket.io 这种方案。

相关信息

Laravel+Uniapp项目中使用广播系统(广播机制终端对象连接) 排名链接
(图片来自网络侵删)
laravel-echo-server:使用 socket.io 机制实现的 broadcasting 服务端laravel-echo:laravel-echo是 laravel broadcasting 的客户端。
注意,laravel-echo 并不是 laravel-echo-server 专属的客户端, laravel-echo 有两种连接机制可以选:pusher 和 socket.io 。
而 laravel-echo-server 是开发出来专门用于 socket.io连接的服务端。
如果你使用的是 pusher,那么不需要使用 laravel-echo-server ,但是你依然要使用 laravel-echoSocket.IO:websocket 的一种nodejs实现。
laravel-echo 如果要使用socket.io 则需要先安装 socket.io-client。
Predis:redis客户端的php实现,如果要使用redis作为广播机制的实现,则需要先安装 predisLaravel Event:广播事件类Laravel Queue:广播机制是基于queue机制来实现的Redis Sub/Pub:Redis的订阅机制。
laravel-echo-server本质上只是一个Redis订阅服务的订阅者。

流程图及过程

Laravel 通过 broadcasting 机制发布一个Event对象到RedisLaravel Queue Worker 读取该Event对象,并使用Redis的Sub/Pub机制将该 Event对象发布出去laravel-echo-server 通过 Redis 的 Sub/Pub机制收听到该 Event由于 laravel-echo 使用 socket.io 跟 laravel-echo-server相连接。
所以 laravel-echo 会通过socket.io将Event对象发送给laravel-echolaravel-echo解析通过 socket.io接收到的 Event对象

广播事件种类

public:谁都可以收听的广播private:只有指定用户可以收到的广播presence:不仅可以收听到跟你有关的广播,还可以跟别的用户互动,适合做聊天室demo 示例构建

1.假设场景

假设我们要使用laravel作为服务端做外卖商家订单推送系统。
商家打开页面后不需要刷新页面即可不断的获取到最新的订单通知。

2.建立广播服务

注册 BroadcastServiceProvider,打开 config/app.php 找到 'provides' 属性,将 BroadcastServiceProvider 前的注释去掉,如下代码示例(app.php 部分代码):

// Package Service Providers... // Application Service Providers... App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, // App\Providers\BroadcastServiceProvider::class, # 去掉注释 App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class,

3.设置广播路由

<?phpuse Illuminate\Support\Facades\Broadcast;/|--------------------------------------------------------------------------| Broadcast Channels|--------------------------------------------------------------------------|| Here you may register all of the event broadcasting channels that your| application supports. The given channel authorization callbacks are| used to check if an authenticated user can listen to the channel.|/Broadcast::channel('App.User.{id}', function ($user, $id) { return (int) $user->id === (int) $id;});# 该channel永远返回true意味着无论收听者是谁,他都会收听到最新的广播。
Broadcast::channel('test_notification', function () { return true;});

4.设置Redis连接

由于广播机制是基于queue机制实现的。
所以queue的存储设置会直接决定广播事件的存储位置。
编辑 .env 文件,修改 QUEUE_DRIVER = redis

QUEUE_DRIVER=redis

5.建立Event

php artisan make:event Notification

6.测试广播

项目根目录下的 app 文件夹中会多出来一个 Events目录,该目录下产生了广播事件类 Notification.php文件。

针对刚生成Notification类进行如下修改:

增加对 ShouldBroadcast 的实现

修改broadcastOn 方法,使用公共广播通道 test_notification

修改构造函数

<?php namespace App\Events; use Carbon\Carbon;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; class Notification implements ShouldBroadcast // 1. 事件是要广播出去的{ use Dispatchable, InteractsWithSockets, SerializesModels; public $message; / Create a new event instance. @return void / public function __construct($message) // 2.广播出去的内容 { $this->message = $message; } / Get the channels the event should broadcast on. @return \Illuminate\Broadcasting\Channel|array / public function broadcastOn() // 3.对那些频道进行广播 { // 创建频道 return new Channel('test_notification'); }}

7.Laravel Queue Worker消费Event

为项目增加 predis依赖,在项目根目录下执行:

composer require predis/predis

新增一个artisan命令来测试是否可以将广播发送到 Redis中,编辑 routes/console.php ,增加 bignews 命令。

Artisan::command('testNotification', function () { broadcast(new Notification('news notification')); $this->comment("news notification");});

执行 testNotification 命令:

$ php artisan testNotificationnews notificatio

通过 redis-cli 查看当前redis中的数据,发现多出来一个queue对象

127.0.0.1:6379> keys 1) "queues:default"

到此 Laravel的广播机制就成功的连接上了 Redis!

新开一个终端窗口,并在根目录下启动 Laravel Queue Worker

php artisan queue:work

之前的终端窗口,再广播一个news Notification:

php artisan testNotification

你可以在queue worker的执行界面看到该Event已经被检测到,并通过Redis Sub/Pub机制传播出去了

$ php artisan queue:work

$ [2023-08-31 23:24:03][37] Processing: App\Events\Notification

还记得之前通过Laravel广播事件之后redis中会产生一个 queue:default对象么?这次如果你快速的通过 keys 命令查询redis中的对象,你会发现 queue:default 每次被产生出来就会迅速的被 queue worker消费掉

127.0.0.1:6379> keys 1) "queues:default"127.0.0.1:6379> keys (empty list or set)

Laravel Queue Worker连接成功!

8.laravel-echo-server 订阅Redis Sub

8.1 安装 laravel-echo-server

再新开一个终端窗口。
由于我们之前已经开了两个终端窗口了,所以这是第三个终端窗口。

先切换到root用户,然后安装laravel-echo-server

npm install -g laravel-echo-server

8.2 初始化

我们切换到项目根目录下,初始化 laravel-echo-server,所有问题都使用默认配置:

$ laravel-echo-server init? Do you want to run this server in development mode? No? Which port would you like to serve from? 6001? Which database would you like to use to store presence channel members? redis? Enter the host of your Laravel authentication server. http://localhost? Will you be serving on http or https? http? Do you want to generate a client ID/Key for HTTP API? No? Do you want to setup cross domain access to the API? NoConfiguration file saved. Run laravel-echo-server start to run server.它会帮你在项目根目录下生成 laravel-echo-server.json 配置文件,默认配置(下面我已经改过)为{"authHost": "http://127.0.0.1:6001","authEndpoint": "/broadcasting/auth","clients": [],"database": "redis","databaseConfig": {"redis": {"port": "6379","host": "127.0.0.1"},"sqlite": {"databasePath": "/database/laravel-echo-server.sqlite"}},"devMode": true,"host": null,"port": "6001","protocol": "http","socketio": {},"secureOptions": 67108864,"sslCertPath": "","sslKeyPath": "","sslCertChainPath": "","sslPassphrase": "","subscribers": {"http": true,"redis": true},"apiOriginAllow": {"allowCors": false,"allowOrigin": "","allowMethods": "","allowHeaders": ""}}

8.3 启动

执行以下命令启动 laravel-echo-server

$ laravel-echo-server start

成功启动后会输出以下日志

我们再回到第一个终端窗口,再次广播一个news Notification。
你会发现 laravel-echo-server 会输出以下日志

laravel-echo-server连接成功!

9.收听广播

$ npm i --save @hyoga/uni-socket.ioimport io from '@hyoga/uni-socket.io';const socket = io('wss://127.0.0.1:6001', { query: {}, transports: [ 'websocket', 'polling' ], timeout: 5000, //设置最大重试次数 reconnectionAttempts: 50, reconnectionDelay: 2000});console.log('ws');socket.on('connect', () => { console.log(socket.id); console.log('ws 已连接'); socket.emit('subscribe', { channel: 'test_notification', //auth: this.options.auth || {}, }); socket.on("App\\Events\\Notification", (...args) => { console.log('收到消息'); console.log(args); });});

标签:

相关文章