laravel echo server redis socket io

Demonstrating Laravel echo, socket io and redis with real world example

In this post i will demonstrate how to use sockets in laravel framework using the new laravel package laravel echo server, redis and socket io.

 

 

Requirements

  • Laravel framework 5.6 or higher
  • Knowledge of laravel events
  • Knowledge of laravel-echo-server
  • socket io

 

Sockets and Broadcasting

Laravel framework always simplify development of web applications using it’s unique features, today i will show one important feature of these which is how to use sockets in laravel with the help of laravel broadcasting. If you refer to laravel docs here you will see a detailed explanation of how to setup broadcasting and how to use it, but let’s first understand what broadcasting means.

Broadcasting always comes with in combination events which means emit an event from one side and catch that event from the other side, the first side here refers to a server and the second side is a client so the server emit events and the client catches and listens for events and do some logic with them. This server works via a socket connection, once this socket connection is turned on it listens for any event that happens in the enclosing scope.

For example if we take a famous example which broadcasting applied mostly is a chat application, in such application specific user joins then another user joins, the socket server notices that then it notifies both users of presence of each other by emitting a presence event. On the other hand if one user sends a message to the other then the server emits an event for sending message, then the other user listens for that message and displays it.

 

Concepts

Channel: A channel in laravel broadcasting is like a tv channel where you register events in that channel and then listen for it, there are different types of channels (Public, Private and Presence). A single channel can contain multiple events.

Event: The event is the core object of using sockets where it defines the item to be emitted to the clients. Events must belong to a channel, in laravel you define the event using a class that implements ShouldBroadcast or ShouldBroadcastNow interface and to fire it you use whether Event::fire(‘event_name’) or event(new EventName()).

 

Laravel Supports multiple broadcasting drivers which are pusher, redis and log. Pusher is simple to use and setup but unfortunately it is not free so In this tutorial i will instead use redis and socketIO.

 

Example overview

To illustraite the idea i will create a simple laravel application, in this example we have a real-estate website where we have two types of users. The first type called “host” and is capable of adding listings and the other type is the “guest” where he is able to view the listing and book it. Now imagine that a new requirement arises, we want to display a notification to the user when another user displays the same listing page so we want to display this notification another user looking at this listing right now .

 

Project setup

Let’s setup a new laravel 5.6 project with composer:

change your db settings:

Next lets create a migration for listings table:

modify database/migrations/XXXX_XX_XX_XXXXX_create_listing_table.php

Now migrate

 

Next let’s insert some dummy data into our table so we will use laravel seeder

Open database/seeds/DatabaseSeeder.php and modify it like this:

 

Now after the table is filled with dummy data let’s generate the authentication, listing model and controller, we will create two pages one that display a listing of items and the other display details of that item.



Generating Auth, Model and Controller

Run this command to generate the auth scaffolding

This will generate the auth routes and the auth views, now let’s create a model and controller to display the listing data.

 

Now make the below modifications to the following files:

app/Listing.php

app/Http/Controllers/ListingController.php

resources/views/layouts/app.blade.php

resources/views/listing.php

resources/views/details.php

routes/web.php

app/Http/Controllers/Auth/LoginController.php

app/Http/Controllers/Auth/RegisterController.php

Well done let’s move to the most important part of this post which is to setup laravel echo and redis

 



Installing dependencies

To prepare laravel echo server and socket io for use we will need to install some required dependencies:

Install npm dependencies

 

Install php redis

 

Install laravel echo server with npm

Next open the .env file and change BROADCASR_DRIVER to redis

 

Preparing laravel echo server

Let’s prepare laravel echo server, to do this we will a config file for laravel-echo-server in our project root directory, fortunately laravel-echo-server can generate this file automatically for us using this command:

It will ask you a set of questions lets keep the defaults for now and be sure to select redis as the database. After it finishes it will generate a json file in your project root called “laravel-echo-server.json” like this one:

Notice the port number, this port is used by the laravel echo server to listen to events, it’s important that no other process in your system takes this port. But we need away to make this port configurable so let’s add it to the .env

Also add this as a javascript variable in main layout

resources/views/layouts/app.blade.php

 

Generating event

Let’s create a new event:

Open app/Events/ListingViewed.php and update as below:

As you see above i have implemented the ShouldBroadcastNow interface and injected the listing model to event constructor, this data will be used when we listen for the event on the client side. Also i have specified that the event will broadcast on public channel with name “listing.{id}” on the method broadcastOn()

 

Firing the event

We need to fire the event when the user views a listing page and if he is authenticated so open app/Http/Controllers/ListingController.php and add this line:

 

Listening for the event

To listen for the event we will call the laravel echo javascript library we just installed above. To do add a new file in resources/assets/js to import laravel echo.

resources/assets/js/laravel-echo-setup.js

As shown we imported laravel echo using Ecmascript6 syntax and then created a new object specifying that we use socket.io as the broadcaster and the host to listen to.

 

Next we will need to add this file to webpack.mix.js to be transpilled to Ecmascript5 

Open webpack.mix.js and add this line:

You can read more about webpack here.

Run this command in terminal to execute webpack scripts:

This will generate a javascript file in public/js/laravel-echo-setup.js , let’s add this script to our resources/views/details.blade.php

resources/views/details.blade.php

Here we updated our view by adding the socket.io script, note that this script is available only when the laravel-socket-server is turned on. Then called window.Echo.channel() method passing in the channel we need to listen to, this channel is same channel we registered the event above.

After that we use the listen() method, here we listened on “ListingViewed” event, this is the class name of the event we just created above.

I want to show notification to other users excluding the current user, so i add a condition like this:

Here i displayed browser notification for testing but you can use any other notification system as you like.



Testing notifications

To test the notifications create two user accounts and login from two different browsers, let’s say chrome and firefox and then in your project root directory run this command to turn on laravel echo server:

If it works successfully it should output

Now try to access any listing in firefox with the first user account and then access the same listing on chrome with the second user account and it will show the notification like this.

laravel socket server notification testing

Share this: