Chat Application Example

Laravel Websockets

Author: Emad Zaamout

Sunday, May 1, 2021

Download at Github

Table of Contents

  1. What is WebSockets?
  2. How do WebSockets work?
  3. What are Pusher Channels?
  4. What is BeyondCode Laravel WebSockets?
  5. Create a new Laravel Project.
  6. Create Database.
  7. Install Laravel Websockets.
  8. Install Pusher PHP Server SDK.
  9. Run Queue and WebSockets Server.
  10. Laravel WebSockets Dashboard.
  11. Configure broadcasting and Websockets.
  12. Create Websockets connect API.
  13. Broadcasting & Channels.
  14. Frontend JavaScript

Introduction

Welcome back,

In this course, we will cover custom Laravel WebSocket Chat Application implementation using the Laravel framework.

We will not be using any third-party vendor for the WebSockets server. We will implement it from scratch, and we will use our server to handle all the WebSockets communications.

Before we get started, dont forget to subscribe to my channel to stay up to date with my latest training videos.

Course Overview

To learn WebSockets, its best to do it by an example.

The first part of the course, I will explain what WebSockets are and how they work.

The reason why I choice a chat application is because it involves everything you need to get started with WebSockets.

Before we get started, I wanted to show you a demo of what we will build first.

This is not a front-end course, so I will not focus on aesthetics but rather on how to establish a two-way communication system between your server and your users devices to provide updates in real-time.

What is WebSockets?

WebSocket is an API that lets you establish a two-way communication system in real-time between a user device and your server.

A user device can be for example, be the users browser or mobile phone or anything that can connect to a server.

To understand why you would want to use web sockets, ill give you a quick example.

So right now, lets say a user visits your website. Your server serves them the result based on your API implementation. Thats one way communication between the user and your server.

Sometimes you need to have two-way communication between your users device, and your server so that you can provide your users updates in real-time.

A great example is chat applications. Lets say one of your users has his mailbox open on his browser and someone sends him a message. Then we will need our servers to communicate with that users browser so that we can update the user interface and maybe display the message or prompt a notification in real-time without having them to reload their browser page.

How do WebSockets work?

WebSockets is basically an exposed API endpoint that you implement on your server.

By exposed I mean anyone can make a request to it.

Depending on your use case, you can have WebSockets endpoints that require authorization.

Whenever you decide to use WebSockets, you should be very cautious. If youre not validating requests, then hackers can take advantage of that.

Connecting to WebSockets is very similar to HTTP requests. However, its not the same. WebSocket is a communication protocol thats like HTTP, but its very different.

HTTP requests are one way. Meaning that a user can make a request to a server. WebSocket protocol is a two-way communication system between a device and a server.

To make any HTTP request on a server, its usually done through ports 80 for HTTP and 443 for HTTPS.

For Example:


            http://ahtcloud.com:80 or https://ahtcloud.com:443
        

WebSockets use a different protocol. But its very similar. To make a WebSocket request, instead of using http, you use ws on port 6001. The https equivalent is wss and you can do that on port 443. It would look something like this:


            ws://192.168.10.1.0:6001 (equivalent for http) or wss://192.168.10.1.0:443 (equivalent for https)
        

What are Pusher Channels?

If you read the Laravel documentation or if you started working in WebSockets, you will hear allot about Pusher.

Pusher Channels is a popular hosted WebSockets solution.

Instead of building your own WebSockets servers, you can just use theirs for a certain price.

In this course, we will learn how to implement our own WebSockets server instead. Its free, very easy to do and gives you full control.

What is BeyondCode Laravel WebSockets?

ByeondCode Laravel WebSockets is a package designed for Laravel 5.7 and up.

It will get your application started with WebSockets very quick.

It can be used as a Pusher replacement.

This means that you can still take advantage of using Laravels Pusher configuration and Pusher SDK without using their servers.

This can get you up and running with websockets real quick.

https://beyondco.de/docs/laravel-websockets/getting-started/introduction

Create a new Laravel Project.

I have already prepared my project on Vagrant Homestead. If you dont know how to set up your local environment, I suggest you watch my previous tutorial on how to set up your local environment.

I am using homestead, so Ill just show you quickly my homestead yaml file.


    ---
    ip: "192.168.10.10"
    memory: 5096
    cpus: 4
    provider: virtualbox
    authorize: ~/.ssh/id_rsa.pub
    keys:
        - ~/.ssh/id_rsa
    networks:
        - type: "public_network"
          bridge: "Killer E2400 Gigabit Ethernet Controller"
    folders:
        - map: D:/websites
          to: /etc/www/code/
    sites:
        - map: local.websocketsexample.com
          to: /etc/www/code/courses/websockets
          php: "8.1"
    features:
        - mysql: true
        - mariadb: false
        - postgresql: false
        - ohmyzsh: false
        - webdriver: false
        - rabbitmq: false
        - redis-server: false
    services:
        - enabled:
           - "mysql"
    ports:
        - send: 80
          to: 8080
        - send: 6001
          to: 6001
        - send: 33060 # MySQL/MariaDB
          to: 3306
        - send: 33060 # MySQL/MariaDB
          to: 3306
        - send: 54320 # postgresql
          to: 5432
        - send: 2222 # ssh tunnel
          to: 22
        

To create a new Laravel project using composer, run the following command:


    composer create-project laravel/laravel websockets
        

Create Database.

Create a new database called laravel-websockets

To run the default Laravel migrations; run the following command:


    php artisan migrate
        

Install Laravel Websockets.

Install using composer:


    composer require beyondcode/laravel-websockets
        

Publish the migration files.


    php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"
        

Run your migrations.


    php artisan migrate.
        

Publish the configuration file.


    php artisan migrate.
        

Install Pusher PHP Server SDK.

First, we will download and use Pusher PHP Server SDK package. This will provide us with a complete WebSocket, and HTTP servers set up.

Install using composer:


    composer require pusher/pusher-php-server
        

Run Queue and WebSockets Server.

To run Laravel Queue:


    php artisan queue:work
        

Note, if your using database as your queue driver, then you will need to create a new jobs table and run your migrations.


    php artisan queue:table
    php artisan migrate
        

To run Laravel WebSockets server:


    php artisan websockets:serve
        

Laravel WebSockets Dashboard.

The Laravel websockets package that we installed comes with a dashboard that you can use.

The path by default is set to "/laravel-websockets". To change the file path you will need to update your path variable value thats declared inside config/websockets.php.

Configure broadcasting and Websockets.

Update your .env file. Make sure to set PUSHER variables:


    BROADCAST_DRIVER=pusher

    PUSHER_APP_ID=staging
    PUSHER_APP_KEY=staging
    PUSHER_APP_SECRET=staging
    PUSHER_APP_CLUSTER=mt1

    LARAVEL_WEBSOCKETS_HOST=127.0.0.1
    LARAVEL_WEBSOCKETS_PORT=6001
        

Create Websockets connect API.

Before we create our API to connect with our websockets. You will need to create a new controller to handle the socket connections.

Create a new SocketsController controller inside app\Http\Controllers\SocketsController.php:


declare(strict_types=1);

namespace App\Http\Controllers;

use Illuminate\Broadcasting\Broadcasters\PusherBroadcaster;
use Illuminate\Http\Request;
use Pusher\Pusher;

class SocketsController
{
    public function connect(Request $request)
    {
        $broadcaster = new PusherBroadcaster(
            new Pusher(
                env("PUSHER_APP_KEY"),
                env("PUSHER_APP_SECRET"),
                env("PUSHER_APP_ID"),
                []
            )
        );

        return $broadcaster->validAuthenticationResponse($request, []);
    }
}
        

Now, lets go ahead and create our new Laravel Websockets Connect API. Update your routes/api.php file. Add the following route:


    Route::post("/sockets/connect", [SocketsController::class, "connect"]);
        

Broadcasting & Channels.

Update your routes/channels.php and add a new channel "SendMessageEvent". By creating a new channel we can have our frontend connect to our websockets server and listen on our broadcasting channel.

We will then use this channel to update our frontend once a new chat message is received. This will allow our frontend to update the chat display.


    Broadcast::channel("SendMessageEvent", function () {
        return [
            "name" => $this->name,
            "message" => $this->message,
            "time" => $this->time
        ];
    });
        

Once we receive a new message. We will update our broadcast channel and pass in our event. We will call our event, SendMessage. Go ahead and create a new folder called "Events" inside your "app" directory.


    namespace App\Event
    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\SerializesModel
    class SendMessage implements ShouldBroadcast
    {
        use Dispatchable, InteractsWithSockets, SerializesModel
        public string $name;
        public string $message;
        public string $time

        public function __construct(string $name, string $message, string $time)
        {
            $this->name = $name;
            $this->message = $message;
            $this->time = $time;

        public function broadcastWith() {
            return [
                "name" => $this->name,
                "message" => $this->message,
                "time" => $this->time
            ];

        /**
        * Get the channels the event should broadcast on.
        *
        * @return  \Illuminate\Broadcasting\Channel|array
        */
        public function broadcastOn()
        {
            return new Channel("SendMessageEvent");
        }
    }
        

Frontend JavaScript

Before we can create our frontend, we will need to create a post API to send a message. Once a message is sent we will then dispatch our event. Our frontend will be listening to our channel through our websockets server.

To make it a little simple, we will just declare our new route inside web.php.


    use App\Events\SendMessage;
    use BeyondCode\LaravelWebSockets\Apps\AppProvider;
    use BeyondCode\LaravelWebSockets\Dashboard\DashboardLogger;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Route;

    Route::get('/', function (AppProvider $appProvider) {
        return view('chat-app-example', [
            "port" => env("LARAVEL_WEBSOCKETS_PORT"),
            "host" => env("LARAVEL_WEBSOCKETS_HOST"),
            "authEndpoint" => "/api/sockets/connect",
            "logChannel" => DashboardLogger::LOG_CHANNEL_PREFIX,
            "apps" => $appProvider->all()
        ]);
    });

    Route::post("/chat/send", function(Request $request) {
        $message = $request->input("message", null);
        $name = $request->input("name", "Anonymous");
        $time = (new DateTime(now()))->format(DateTime::ATOM);
        if ($name == null) {
            $name = "Anonymous";
        }
        SendMessage::dispatch($name, $message, $time);
    });
        

Our final step is to create our frontend. Create a new view file (inside "resources/views/chat-app-example.blade.php")

resources/views/chat-app-example.blade.php

Other Posts

Windows WSL 2 Docker Tutorial Course Image

Tuesday, August 22 2023

Deploy any Dockerized application using AWS Course

Author: Emad Zaamout
Amazon Elastic Container Registry (AWS ECR)

Tuesday, June 27 2023

Amazon Elastic Container Registry (AWS ECR)

Author: Emad Zaamout
Custom Docker Images Course

Tuesday, June 27 2023

Custom Docker Images

Author: Emad Zaamout
Laravel Makefiles Course Image

Sunday, Oct 24, 2022

Laravel Makefiles

Author: Emad Zaamout
Windows WSL 2 Docker Tutorial Course Image

Sunday, Oct 24, 2022

Laravel Docker Course

Author: Emad Zaamout
Windows WSL 2 Docker Tutorial Course Image

Sunday, Oct 24, 2022

Laravel 9 Complete Course | Blog Implementation

Author: Emad Zaamout
Windows WSL 2 Docker Tutorial Course Image

Sunday, Oct 24, 2022

Windows WSL 2 Docker Tutorial

Author: Emad Zaamout
GIT Crash Course using Bitbucket By Emad Zaamout

Saturday May 1, 2021

Laravel Websockets Example Chat Application

Author: Emad Zaamout
GIT Crash Course using Bitbucket By Emad Zaamout

Saturday May 1, 2021

Laravel API Course | MVCS Repository Pattern

Author: Emad Zaamout
GIT Crash Course using Bitbucket By Emad Zaamout

Saturday October 24, 2021

Git Tutorial - Git Crash Course using BitBucket

Author: Emad Zaamout
What is AWS Elastic Load Balancer By Emad Zaamout

Monday October 18, 2021

AWS Elastic Load Balancing

Author: Emad Zaamout
DMARC SPF DKIM Course By Emad Zaamout

Saturday October 16, 2021

Email DNS Master Course - SPF + DKIM + DMARC

Author: Emad Zaamout
Email SPF Record Tutorial – Sender Policy Framework (SPF) | Prevent Email Spoofing | DNS Course By Emad Zaamout

Saturday October 16, 2021

Email SPF Record Tutorial – Sender Policy Framework (SPF) | Prevent Email Spoofing | DNS Course

Author: Emad Zaamout
DMARC Tutorial - How to set up DNS DMARC record | Protect Your Doman By Emad Zaamout

Saturday October 16, 2021

DMARC Tutorial - How to set up DNS DMARC record | Protect Your Doman

Author: Emad Zaamout
Git Hooks Crash Course

Sunday, September, 2021 (MDT)

Git Hooks Crash Course

Author: Emad Zaamout
Laravel CI\CD using AWS RDS EC2 S3 CodeDeploy BitBucket By Emad Zaamout

Friday, September 17, 2021 (MDT)

Laravel DevOps Tutorial - Laravel Deployment Automation CI\CD using AWS RDS EC2 S3 CodeDeploy BitBucket

Author: Emad Zaamout
Deploy any Laravel app in AWS (Amazon Web Services) By Emad Zaamout

Monday, April 19, 2021 (MDT)

Deploy any Laravel App in AWS (Amazon Web Services)

Author: Emad Zaamout
Fisher Yates Shuffle Algorithm Implementation? By Emad Zaamout

Saturday, September 26, 2020 (MDT)

Find out the secrets, tips and tricks to ranking number 1 on Google.

Author: Emad Zaamout
Fisher Yates Shuffle Algorithm Implementation? By Emad Zaamout

Saturday, September 26, 2020 (MDT)

Fisher - Yates Shuffle Algorithm Implementation

Author: Emad Zaamout
What Is an Ecommerce Website & How to Get Started (2020 guide)? By Emad Zaamout

Saturday, September 26, 2020 (MDT)

What Is an Ecommerce Website & How to Get Started (2020 guide)?

Author: Emad Zaamout
5 Reasons Why You Need A Website Calgary Website Design Company AHT Cloud

Thursday, May 7, 2020

5 Reasons Why You Need A Website

Author: Emad Zaamout
Whats Involved in Creating a Unique Custom Website? By Emad Zaamout

Thursday, May 7, 2020

Whats Involved in Creating a Unique Custom Website?

Author: Emad Zaamout
SEO Checklist By Emad Zaamout

Thursday, May 7, 2020

SEO CHECKLIST

Author: Emad Zaamout

GET YOUR FREE ESTIMATE

CONTACT US TODAY FOR YOUR FREE CONSULTATION!


Contact us today to discuss your goals and we will create a simple roadmap to get you there. We look forward to speaking with you!

Main Office

Phone:   1 587-834-6567
Email:   support@ahtcloud.com
32 Westwinds Crescent NE #130
Calgary, AB T3J 5L3, CA

Products

TMS
Cloud Based Transportation Management System


Hours Of Operation

Monday 8:00 am - 5:00 pm
Tuesday 8:00 am - 5:00 pm
Wednesday 8:00 am - 5:00 pm
Thursday 8:00 am - 5:00 pm
Friday 8:00 am - 5:00 pm
Saturday Closed
Sunday Closed