Categories
Laravel JavaScript

Let’s configure our own WebSocket Server for Laravel Echo

I assume you have comfortable with Laravel Broadcasting. By default, Laravel has the following four broadcast drivers.

  1. Log
  2. Pusher
  3. Redis
  4. 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.

By Mehedi Hasan

Hi!
I am Mehedi Hasan, work as a Software Engineer at weDevs. I love to experiment with the latest tech and make something that solves some problems of others and mine. Also in my free time, I like to read religious books on Islam.

Leave a Reply

Your email address will not be published. Required fields are marked *