Sometimes when we simply look at the Laravel manual there will be some confusion, such as system services under the authorization and events, these functional services, what is the application scenario, in fact, if you have not experienced a certain amount of development experience of these doubts is very normal things, But when we think more about our work, we find that sometimes we have seen these services in fact. Here's a simple example of events and event sniffing you'll find.
This example is about the implementation of the browsing number of the article, when users view the article, the number of browsing will increase by 1, the user view article is an event, there is an event, you need an event listener, to monitor the event after the corresponding operation (article browsing number plus 1), in fact, this monitoring mechanism in Laravel is implemented through the observer pattern.
Registering events and listeners
First we need to register the event listener mapping relationship in the eventserviceprovider.php in the app/providers/directory, as follows:
protected $listen = ['
app\events\blogview ' => [
' App\listeners\blogviewlistener ',
],
];
Then the project root directory executes the following command
PHP Artisan Event:generate
When this command is complete, blogview.php and blogviewlistener.php files are automatically generated in the App/events and App/listensers directories respectively.
Defining events
<?php
namespace app\events;
Use app\events\event;
Use App\post;
Use Illuminate\queue\serializesmodels;
Use Illuminate\contracts\broadcasting\shouldbroadcast;
Class Blogview extends Event
{use
serializesmodels;
/**
* Create A new event instance.
*
* @return void
*
/Public Function __construct (Post $post)
{
$this->post = $post;
}
/**
* Get the channels the event should is broadcast on.
*
* @return Array
*
/Public Function Broadcaston ()
{return
[]
}
}
In fact, you'll find that the event class simply injects a post instance and does not contain unnecessary logic.
Defining listeners
the event listener receives an event instance in the handle method, and the Event:generate command automatically imports the appropriate event class and type hint events in the handle method. Within the handle method, you can perform any logic required to respond to the event, and our code is implemented as follows:
<?php namespace App\listeners;
Use App\events\blogview;
Use Illuminate\queue\interactswithqueue;
Use Illuminate\contracts\queue\shouldqueue;
Use Illuminate\session\store;
Class Blogviewlistener {protected $session;
/** * Create the event listener.
* * @return void */Public function __construct (Store $session) {$this->session = $session;
}/** * Handle the event. * * @param blogview $event * @return void */Public function handle (Blogview $event) {$post = $event
;p OST; Make a decision to see if (! $this->hasviewedblog ($post)) {//Save to database $post->view_cache = $post->view_cach
e + 1;
$post->save ();
After reading it will be saved to session $this->storeviewedblog ($post); } protected function Hasviewedblog ($post) {return array_key_exists ($post->id, $this->getviewedblogs ())
;
} protected function Getviewedblogs () {return $this->session->get (' viewed_blogs ', []); } protected function Storeviewedblog ($post) {$key = ' viewed_blogs. '
$post->id;
$this->session->put ($key, Time ());
}
}
Some of the logic is also explained in the comments.
Triggering events
after event and event monitoring is complete, all we have to do is implement the entire listener, that is, to trigger the user to open the article event here we use and event provides the fire method as follows:
<?php
namespace App\http\controllers;
Use Illuminate\http\request;
Use App\post;
Use illuminate\support\facades\event;
Use app\http\requests;
Use App\events\blogview;
Use App\http\controllers\controller;
Class BlogController extends Controller
{public
function showpost ($slug)
{
$post = post:: Whereslug ($slug)->firstorfail ();
Event::fire (New Blogview ($post));
Return view (' Home.blog.content ')->withpost ($post);
}
Now open the page and discover that the ' View_cache ' in the database is 1 normal, so the whole thing is done.
Event broadcast
Introduction:
Laravel 5.1 added the function of the event broadcast, the role is to trigger the event in the server through the WebSocket service to inform the client, that is, the browser, client JS based on the event received to make the corresponding action. This article will use simple code to show the process of an event broadcast.
Depend on:
- Redis
- Nodejs, Socket.io
- Laravel 5.1
Configuration:
- In config/broadcasting.php, the following configuration ' default ' => env (' broadcast_driver ', ' Redis '), using Redis as a way of communicating PHP and JS.
- Redis connection is configured in config/database.php.
To define a broadcast event:
The event class must implement a Illuminate\contracts\broadcasting\shouldbroadcast interface and implement a method Broadcaston, depending on the description of the Laravel documentation, to allow events to be broadcast. Broadcaston returns an array containing the channel (channel) to which the event is sent. As follows:
namespace App\events;
Use app\events\event;
Use Illuminate\queue\serializesmodels;
Use Illuminate\contracts\broadcasting\shouldbroadcast;
Class Someevent extends Event implements Shouldbroadcast
{use
serializesmodels;
Public $user _id;
/**
* Create A new event instance.
*
* @return void
*
/Public Function __construct ($user _id)
{
$this->user_id = $user _id;
}
/**
* Get the channels the event should is broadcast on.
*
* @return Array
/Public Function Broadcaston ()
{return
[' Test-channel '];
}
Data to be broadcast:
By default, all public properties in an event are serialized and broadcast. The above example is $user_id this attribute. You can also use the Broadcastwith method to clearly indicate what data to broadcast. For example:
Public Function Broadcastwith ()
{return
[' user_id ' => $this->user_id];
}
Redis and WebSocket servers:
Need to start a Redis, event broadcast is mainly dependent on the Redis sub/pub function, you can see the Redis document
You need to start a websocket server to communicate with the client, we recommend using Socket.io, the code is as follows:
var app = require (' http '). Createserver (handler);
var io = require (' Socket.io ') (app);
var Redis = require (' Ioredis ');
var Redis = new Redis (' 6379 ', ' 192.168.1.106 ');
App.listen (6001, function () {
Console.log (' Server is running! ');
});
function handler (req, res) {
res.writehead);
Res.end (")";
Io.on (' Connection ', function (socket) {
console.log (' connected ');
});
Redis.psubscribe (' * ', function (err, count) {
console.log (count);
});
Redis.on (' Pmessage ', function (subscribed, channel, message) {
console.log (subscribed);
Console.log (channel);
Console.log (message);
Message = json.parse (message);
Io.emit (Channel + ': ' + message.event, message.data);
});
Note Here is the definition of the Redis.on method, after receiving the message, send an event to the client, the event name is Channel + ': ' + message.event.
Client code:
Client We also use Socket.io, as a test, the code as simple as possible, just print a received data. As follows:
var socket = io (' http://localhost:6001 ');
Socket.on (' Connection ', function (data) {
console.log (data);
});
Socket.on (' Test-channel:app\\events\\someevent ', function (message) {
console.log (message);
});
Console.log (socket);
Server triggers event:
Define an event trigger directly in the router. As follows:
Route::get ('/event ', function () {
event::fire (new \app\events\someevent (3));
Return to "Hello World";
};
Test:
- Start Redis
- Start WebSocket
- Open a page with client-side code to see that WebSocket has been successfully connected.
- Triggers an event to open another page localhost/event.
At this point, you can find that the first page of the console print out the Object{user_id:3}, indicating the success of the broadcast.