转载请注明出处: 子恒博客
本文的链接地址: https://blog.phpat.com/web/557.html
Laravel Websockets 需要laravel 5.7+,所以需要以后更新了laravel之后才能做这个功能。
目前产品的任务系统靠ajax轮询实现,每5秒刷新一次数据,这样的做法每次都需要消耗服务器资源,而且会影响用户体验。
使用laravel的广播系统可以做到由服务器实时通知客户端更新任务状态,且不需要轮询,底层是websockets技术。
广播驱动程序是用来处理ws/wss请求, 本次使用的是: Laravel Websockets
Laravel Websockets 需要laravel 5.7+
通过composer可以安装:
composer require beyondcode/laravel-websockets
生成websockets配置文件config/websockets.php
:
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"
启动程序进程:线上可以添加到后台运行
php artisan websockets:serve
config/broadcasting.php
配置文件中包含每个驱动程序的配置示例。
Provider: 在广播事件之前,首先需要注册 App\Providers\BroadcastServiceProvider
。在 config/app.php
配置文件的 providers 数组中取消注释。这个BroadcastServiceProvider包含注册广播授权路由和回调所需的代码。
队列配置:您还需要配置和运行 queue worker。所有事件广播都是通过排队作业完成的,因此您的应用程序的响应时间不会受到广播事件的严重影响。
使用 Composer 包管理器安装 Pusher Channels PHP SDK
composer require pusher/pusher-php-server
在.env中配置pusher相关配置
BROADCAST_DRIVER=pusher
...
PUSHER_APP_ID=my_pusher
PUSHER_APP_KEY=my_pusher
PUSHER_APP_SECRET=my_pusher
PUSHER_HOST=127.0.0.1
PUSHER_PORT=6001
PUSHER_SCHEME=http
PUSHER_APP_CLUSTER=mt1
新建任务状态事件, 注意需要集成ShouldBroadcast
,事件创建了一个规则为task.{user_id的md5}
的私人频道。
<?php
namespace App\Events;
use App\Models\AnalysisTaskModel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class TaskStateEvent implements ShouldBroadcast
{
public $task;
public function __construct($id)
{
$this->task = AnalysisTaskModel::query()->find($id);
}
public function broadcastOn()
{
return new PrivateChannel('task.'. md5($this->task->user_id));
}
/**
* 获取要广播的数据。
*
* @return array
*/
public function broadcastWith()
{
return ['id' => $this->task->id, 'state' => $this->task->state];
}
}
在config/channels.php
中添加:
Broadcast::channel('task.{auth}', function ($user, $auth) {
return md5($user->id) === $auth;
});
任务状态由python改变,需要给python提供一个接口,来让python告诉php某个任务的状态发生了改变。
php添加路由:
Route::GET('task/state', 'AnalysisTask@stateChange');
在AnalysisTask控制器中新建函数:
函数接收任务id作为参数,并传递给事件系统。
/**
* 通知客户端,任务状态改变
* @param Request $request
* @return void
*/
public function stateChange (Request $request) {
event(new TaskStateEvent($request->get('id')));
}
python可以执行curl来访问该接口:
# shell
curl http://xxxxxxx/api.php/task/state?id=165
Laravel Echo 是一个 JavaScript 库,可以轻松订阅频道和收听服务器端广播驱动程序广播的事件。 你可以通过 NPM 包管理器安装 Echo。在此示例中,我们还将安装 pusher-js
包,因为我们将使用 Pusher Channels 广播器:
# npm
npm install --save-dev laravel-echo pusher-js
# yarn
yarn add laravel-echo pusher-js
在任务列表页面创建Echo实例:
import Echo from 'laravel-echo'
import Pusher from 'pusher-js'
# 以下可以写到method中
const client = new Pusher('my_pusher', {
forceTLS: document.location.protocol === 'https:',
wsHost: window.location.hostname,
wssHost: window.location.hostname,
wsPort: 6001,
wssPort: 6001,
auth: {
headers: {}
},
disableStats: true,
cluster: 'mt1',
authEndpoint: '/api.php/broadcasting/auth'
})
this.echo = new Echo({
broadcaster: 'pusher',
client: client
})
console.log(this.userInfo)
const auth = this.userInfo.auth
this.echo.private(`task.${auth}`)
.listen('TaskStateEvent', (e) => {
console.log(e)
this.list.map(item => {
if (item.id === e.id) {
item.state = e.state
}
})
})
在mounted中设置3秒后启动,原因是可能不小心点击到本页面(如何确保userInfo一定存在?)
this.kit = setTimeout(this.connectWebSockets, 3000)
在beforeDestroy钩子中销毁定时器并离开广播频道:
const auth = this.userInfo.auth
this.echo.leave(`task.${auth}`)
if (this.kit) {
clearTimeout(this.kit)
}
转载请注明出处: 子恒博客
本文的链接地址: https://blog.phpat.com/web/557.html
最近更新:更新到v2.5.7
请求中为数字/布尔的字段要多加注意,...
基于emlog开发的微信小程序
仿小米论坛版本更新V2.0,本次暂时...
element-ui el-tabl...
@子恒:😂躺平吧,世界都跟你没关系
😂fenxi.me这个域名真好
#友情链接#
你写得非常清晰明了,让我很容易理解你的观...
#Emlog插件RSS订阅器发布#
一直到今天,还没10天,我支付宝里仅剩7...
@樊鑫:不支持,仅支持pro版本,可以在...
#Beginning-Pro发布,Emlog-Pro + Beginning-Pro, 更Pro#
支持5.3吗?在哪里购买/下载?
#Beginning-Pro发布,Emlog-Pro + Beginning-Pro, 更Pro#