Laravel进阶系列笔记--(十九)Laravel 广播-公共频道的使用
作者:温新
时间:2021-07-29
hi,我是温新,一名PHPer
本系列采用Laravel8.x演示。
本篇文章基于Pusher
进行演示性学习记录。Pusher
是在国外,在国内一般都不使用它。关于文档,介绍的都是挺粗略的,有问题就疯狂的去百度、谷歌吧。百度转来转去太严重了,对于现在的问题,有的几乎都是无解,只有靠自己去解决。
本篇文章的目的在于快速使用Laravel广播,同时,本篇文章使用一个全新的Laravel项目进行演示记录。
Laravel基于Pusher公共广播的快速使用
第一步:创建Pusher App应用
首先,puhser.com
进行注册或登录后,创建一个channel
频道应用,创建后会生成一个相关的App key
(这就是我们所需要的东西)。
第二步:创建广播事件并修改
php artisan make:event DemoEvent
// 修改内容
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// DemoEvent.php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(152, 26, 26)"><?</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">namespace</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">App\Events</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Broadcasting\Channel</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Broadcasting\InteractsWithSockets</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Broadcasting\PresenceChannel</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Broadcasting\PrivateChannel</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Contracts\Broadcasting\ShouldBroadcast</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Foundation\Events\Dispatchable</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">use</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Illuminate\Queue\SerializesModels</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 继承广播接口 ShouldBroadcast</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">SayHelloEvent</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">implements</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">ShouldBroadcast</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">{</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 保存消息</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$msg</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(170, 17, 17)">''</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">__construct</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$msg</span>)</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$this</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-></span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">msg</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span> <span style="box-sizing: border-box;color: rgb(0, 85, 170)">$msg</span>;</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">public</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> <span style="box-sizing: border-box;color: rgb(0, 0, 255)">broadcastOn</span>()</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">return</span> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">new</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">Channel</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'demo'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> }</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">}</span>
第三步:路由中广播事件
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// web.php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 订阅用户</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">Route</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">get</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'/'</span>, <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span> () {</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(119, 0, 136)">return</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">view</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'welcome'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">});</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 广播事件</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">Route</span>::<span style="box-sizing: border-box;color: rgb(0, 0, 0)">get</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'demo/{msg}'</span>, <span style="box-sizing: border-box;color: rgb(119, 0, 136)">function</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$msg</span>){</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">event</span>(<span style="box-sizing: border-box;color: rgb(119, 0, 136)">new</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">\App\Events\DemoEvent</span>(<span style="box-sizing: border-box;color: rgb(0, 85, 170)">$msg</span>));</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">dd</span>(<span style="box-sizing: border-box;color: rgb(170, 17, 17)">'succ'</span>);</span><br></br><span style="box-sizing: border-box;padding-right: 0.1px">});</span>
有时候由于众所周知的原因,会失败。
第四步:安装Pusher PHP SDK包
composer require pusher/pusher-php-server "~4.0"
第五步:Laravel Echo服务安装
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">npm</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">install</span> <span style="box-sizing: border-box;color: rgb(152, 26, 26)">--</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">save</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">laravel</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(119, 0, 136)">echo</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">pusher</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">-</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">js</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">npm</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">install</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">npm</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">run</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0)">watch</span></span>
第六步:修改配置
1)将驱动修改为pusher
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// .env</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">BROADCAST_DRIVER</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">pusher</span></span>
1)配置相关key
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// .env</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">PUSHER_APP_ID</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">你的ID</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">PUSHER_APP_KEY</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">你的KEY</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">PUSHER_APP_SECRET</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">你的SECRET</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">PUSHER_APP_CLUSTER</span><span style="box-sizing: border-box;color: rgb(152, 26, 26)">=</span><span style="box-sizing: border-box;color: rgb(0, 0, 0)">ap3</span></span>
2)打开广播服务
<span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// config/app.php</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box"></span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(170, 85, 0)">// 打开这个注释,使之生效</span></span><br></br><span style="box-sizing: border-box;padding-right: 0.1px"><span style="box-sizing: border-box;color: rgb(0, 0, 0)">App\Providers\BroadcastServiceProvider</span>::<span style="box-sizing: border-box;color: rgb(119, 0, 136)">class</span>,</span>
4)配置广播服务连接
// config/boradcasting.php
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true,
'curl_options' => [
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
]
],
],
【报错】若在运行过程报错PusherBroadcaster exception "Failed to connect to Pusher" when running in queue
。
【解决】选项中添加如下配置,跳过SSL验证。
// 加了这个有时候也会连接失败
'curl_options' => [
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
]
第七步:js客户端配置
// resources/js/bootstrap.js
import Echo from 'laravel-echo';
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: '你的Pusher KEY',
cluster: 'ap3',
forceTLS: true
});
// 频道监听
window.Echo.channel('demo')
.listen('DemoEvent', (e) => {
let hobj = document.getElementById('msgmsg');
hobj.innerText = e.msg;
console.log(e)
});
第八步:前端客户端订阅
// resources/welcome.blade.php
<meta name="csrf-token" content="{{ csrf_token() }}">
<script src="{{ mix('js/app.js') }}"></script>
<h3 id="msgmsg"></h3>
只要前端页面引入了
js/app.js
文件,就说明是我们的订阅用户,可以收到广播的信息。
第九步:浏览器访问
准备两个浏览器,我用的是谷歌与获取。
谷歌浏览器充当订阅用户;火狐充当信息广播者。
1)谷歌浏览器打开2个页面,都打开首页(打开后什么都不动,静静地接收消息即可)。
2)火狐浏览访问demo/{msg}
路由,如demo/ziruchu
。如此,广播信息已发送。
3)谷歌浏览器两个查看信息,就会发现,没有刷新,信息已经更新了。
我是温新
每天进步一点点,就一点点