I assume you have comfortable with Laravel Broadcasting. By default, Laravel has the following four broadcast drivers.
- Log
- Pusher
- Redis
- Null
We will talk about Redis Driver today. Redis has the characterized channel-based messaging system, It’s called Publish and Subscribe or Pub/Sub. When an event is broadcast on our server, Laravel publishes that event in the specific Redis channel which is defined on event class.
On the other side, a server listening or subscribed to the Redis channel. When an event came to the server broadcast that event to the actual client via WebSocket.
Let’s build our WebSocket server.
First, we will need to install the laravel-echo-server NodeJS package on our server which is perfectly compatible with Laravel Echo.
Here is the sample code you have to write
const server = require('laravel-echo-server');
server.run({
authHost: "http://your-app-url.test",
authEndpoint: '/broadcasting/auth', // laravel auth end point
devMode: false,
port: "6001"
});
Then run the file with any background process manager. That’s it! you have just built a WebSocket server.
Configure the database for storing presence channel members you need to put the following redis
or sqlite
configuration.
{
"database":"DATABASE_YOR_ARE_USE",
"databaseConfig":{
"redis":{
"host":"REDIS_HOST",
"port":"REDIS_PORT",
"keyPrefix":"REDIS_KEY_PREFIX",
"password": "REDIS_PASSWORD"
},
"sqlite":{
"databasePath":"/database/data.sqlite"
}
}
}
Currently, we are using ws://
protocol which is not secure, all data are now transmitted and received as plain. Let’s make it secure and use wss://
protocol. We can easily use SSL by using the following SSL configuration.
{
"sslCertPath": "SSL_CERT_PATH",
"sslKeyPath": "SSL_KEY_PATH",
"sslCertChainPath": "SSL_CERT_CHAIN_PATH",
"sslPassphrase": "SSL_PASSPAHRASE",
}
Now, Let’s configure our Laravel App
First, we will need to install the following two npm packages
Then write the following code to your application javascript file and transpile using any transpiler, like babel.js
import Echo from 'laravel-echo';
window.io = require('socket.io-client');
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
});
Hooray, now you are able to listen any channel events from the WebSocket server. Such as
// Listening Public Channel
Echo.channel('posts')
.listen('OrderShipped', (e) => {
console.log(e.order.name);
});
// Listening Private Channel
Echo.private('users.1')
.listen('NewMessage', (e) => {
console.log(e.message)
});
// Listening Presence Channel
Echo.join(`chat.${roomId}`)
.here((users) => {
//
})
.joining((user) => {
console.log(user.name);
})
.leaving((user) => {
console.log(user.name);
});
To publish an event you need to change BROADCAST_DRIVER
to redis
. Then register Broadcast routes, to the routes/channels.php
file and finally, your event class need to implement the ShouldBrodcast interface. Here is an example event class
namespace App\Events;
use App\Post;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class PostCreated implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* @var Post
*/
public $post;
/**
* Create a new event instance.
*
* @param $post
*/
public function __construct($post)
{
$this->post = $post;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return [
new Channel('posts'),
new PrivateChannel('posts.' . auth()->id())
];
}
}
And broadcast it using broadcast or event helper function or Event facade.
event(new PostCreated($post));
// or
Event::fire(new PostCreated($post));
// or
PostCreated::broadcast($post);
// or
broadcast(new PostCreated($post));
NOTE: If you are use broadcast
helper, Then you can able to broadcast everyone except you by chaining toOthers()
method. Like this
broadcast(new PostCreated($post))-> toOthers();
To learn more visit here. There are lots of options available in this package.