Laravel进阶系列笔记--(十九)Laravel 广播-公共频道的使用

作者: 温新

分类: 【Laravel】

阅读: 1835

时间: 2021-08-31 05:33:10

作者:温新

时间: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)谷歌浏览器两个查看信息,就会发现,没有刷新,信息已经更新了。

我是温新

每天进步一点点,就一点点

请登录后再评论