Laravel 实作 Event & Pusher篇

我们所熟知的Http server-client架构一向都是由client向server发送请求,server再吐回对应的内容。
那假如今天我们希望能在server资料库被更动时立即通知client端,即时更新使用者介面,除了client端不断的轮询来取得后端资料外,是否有更高端、有效率的方式?
我们可以透过WebSocket实作上述的功能,Laravel中的BroadCast支援Redis和Pusher这两个服务,而这篇文章会示範如何透过简单的pusher来完成主动发送事件内容到前端画面

event

第一步:注册eventServiceProvider到Laravel Container中

先在eventServiceProvider中加入

        'App\Events\Event名称' => [                'App\Listeners\Event名称',        ],

範例--新增食物:

 'App\Events\FoodAdded' => [            'App\Listeners\FoodAddedListener',        ],

接着用artisan产生event $php artisan event:generate

第二步:撰写event内容

event class里描述的是该事件的内容,事件如何才会被触发则是在controller中被定义
範例是新增食物主动推播到订阅指定餐厅的频道的事件
专案目录下的app/Event/FoodAdded.php

<?phpnamespace App\Events;//加入会用到的modeluse App\Food;use App\Restaurant;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 FoodAdded implements ShouldBroadcast //若是主动发送推播通知的事件,这边要改成ShouldBroadcast{    use Dispatchable, InteractsWithSockets, SerializesModels;    public $restaurant;    public $food;    public $class = 'food added';    /**     * Create a new event instance.     *     * @return void     */    public function __construct(Food $food)    {   //这边描述的是推播通知的内容        $this->food = $food;        $this->restaurant = Restaurant::find($food->restaurant_id);    }    /**     * Get the channels the event should broadcast on.     *     * @return \Illuminate\Broadcasting\Channel|array     */    public function broadcastOn()    {        //定义新增食物的通知只会发送到指定的餐厅        return ['food-channel.'.$this->restaurant->id];    }    public function broadcastAs()    {        //命名推播的事件        return 'food-event';    }}

FoodController.php

function store(Request $request)    {    //...       $food = Food::create([                'name' => $request->name,                'remaining' => $request->remaining,                'original_price' => $request->original_price,                'discounted_price' => $request->discounted_price,                'image' => $parameters['image'],                'restaurant_id' => $request->restaurant_id,            ]);        //每当该餐厅有食物上架时,会触发FoodAdded事件,发送推播通知订阅该餐厅的频道        event(new FoodAdded($food));        return response()->json($food, 200);    }

Pusher

此範例用Pusher来实作推播通知
首先要在专案目录下安装pusher套件 composer require pusher/pusher-php-server
接着更改.env内容:

BROADCAST_DRIVER=pusher//以下栏位要先去pusher官网申请一组专案,申请完后即可在官网拿到以下四个栏位PUSHER_APP_ID='你的pusher app id'PUSHER_APP_KEY='你的pusher app key'PUSHER_APP_SECRET='你的pusher app secret'PUSHER_APP_CLUSTER='你的pusher app cluster'MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

我写的是后端api,要怎么知道推播通知有没有成功?

Pusher官网有提供一个简单的blade範例来检查自己写的推播通知事件是否能成功发送

<!DOCTYPE html><head>    <title>New Food Pusher Test</title>    <script src="https://js.pusher.com/5.1/pusher.min.js"></script>    <script>        var restaurant_id = 2; //测试2号餐厅食物上架时能不能收到主动发送的通知        // Enable pusher logging - don't include this in production        Pusher.logToConsole = true;        var pusher = new Pusher('{{env('MIX_PUSHER_APP_KEY')}}', {            cluster: '{{env('MIX_PUSHER_APP_CLUSTER')}}',            forceTLS: true        });        var channel = pusher.subscribe('food-channel.'+restaurant_id);        channel.bind('food-event', function(data) {            console.log('Pusher');            alert(JSON.stringify(data));        });    </script></head><body><h1>New Food Pusher Test</h1><p>    Try publishing an event to channel <code>food-channel+restaurant_id</code>    with event name <code>food-event</code>.    <script>    </script></p></body>

遇到的issue

浏览器的console:
pusher.min.js:8 Pusher : : [{"type":"WebSocketError","error":{"type":"PusherError","data":{"code":4005,"message":"Path not found"}}}]

Solution:
.env要加上

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

2.前端看不到pusher该显示的资料
Solution:检查 .env

BROADCAST_DRIVER=pusher

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章