Realtime chat message application using socket.io, redis, express and nodejs in Laravel 8

Laravel provides easy integration with Node application, from which you can create real time message, push notification system. In this article we will create realtime chat messaging application using socket.io, redis, express and nodejs in Laravel 8.

In this tutorial article, we will go through step by step in creating application from the scratch.

  • Step 1: Laravel setup
  • Step 2: Install NodeJS
  • Step 3: Install npm
  • Step 4: Install Redis server
  • Step 5: Install Express.js
  • Step 6: Install predis/predis package
  • Step 7: Create server.js file
  • Step 8: Create Laravel authentication
  • Step 9: Create routes and controller
  • Step 10: Create view file

So let's get started.

Step 1: Laravel setup

First of all, Open Terminal or CMD and create a fresh Laravel application using composer command.

composer create-project laravel/laravel chat

Now go to the project root directory in Terminal.

cd chat

Step 2: Install NodeJS

Now install NodeJS in Ubuntu system. If you have already installed, then skip this step. Update package repository and then install NodeJS.

sudo apt update
sudo apt install nodejs

Step 3: Install npm

npm is NodeJS package manager which downloads and manage pacakges. Install npm package if you don't have.

sudo apt install npm

Step 4: Install Redis server

Redis is in-memory data structure store, cache and message broker which is required for realtime chat messages. So we need to install Redis server.

sudo apt install redis-server

Step 5: Install Express.js

Express.js is Node.js web application backend framework building web applications and API. We will install Express.js with redis and socket.io using npm.

npm install express redis socket.io --save

Step 6: Install predis/predis package

The last installation we required is Redis client for PHP. We will install it by composer command.

composer require predis/predis

In your config/app/php file add the line in $providers array.

'providers' => [
    'Redis' => Illuminate\Support\Facades\Redis::class,
],

And add below line in $aliases array.

'aliases' => [
    'PRedis'    => 'Illuminate\Support\Facades\Redis'
], 

Now we have installed and downloader all the required softwares and application.

Step 7: Create server.js file

Now in this step, we will create nodejs folder in the root Laravel project. In this project we will add new server.js file. This file contains realtime chat message logic.

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('redis');
 
server.listen(8890);
io.on('connection', function (socket) {
 
    console.log("client connected");
    var redisClient = redis.createClient();
    redisClient.subscribe('message');
 
    redisClient.on("message", function(channel, data) {
        socket.emit(channel, data);
    });
 
    socket.on('disconnect', function() {
        redisClient.quit();
    });
});

Step 8: Create Laravel authentication

Obviously we need authentication for chat system. We will use Laravel Breeze for authentication. Run below commands one by one. It will install Laravel Login and Register module.

composer require laravel/breeze

php artisan migrate

php artisan breeze:install

npm install
npm run dev
php artisan migrate

Step 9: Create routes and controller

In this step we will create new route to send message and create controller for the logic.

In the routes/web.php file add new route.

Route::post('sendmessage', [ChatController::class, 'sendMessage'])->name();

We will also need to create controller which handle the routes.

php artisan make:controller ChatController

Now open this controller class at app/Http/Controller/ChatController.php file and add new methods.

<?php

namespace App\Http\Controllers;

use Request;
use PRedis;
use App\Http\Requests;
use App\Http\Controllers\Controller;
 
class ChatController extends Controller
{
    public function __construct()
    {
        $this->middleware('guest');
    }

    public function sendMessage(Request, $request)
    {
        $redis = PRedis::connection();
        
        $data = ['message' => Request::input('message'), 'user' => Request::input('user')];
        
        $redis->publish('message', json_encode($data));
        
        return response()->json(['success' => true]);
    }
}

Step 10: Create view file

In the last step, we will need view to send message.

@extends('layouts.app')
@section('content')
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.1.2/socket.io.js"></script>
<div class="container spark-screen">
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <div class="panel panel-default">
                <div class="panel-heading">Chat Message Module</div>
                <div class="panel-body">
                    <div class="row">
                        <div class="col-lg-8" >
                            <div id="messages" style="border: 1px solid #121212; margin-bottom: 5px; height: 250px; padding: 2px; overflow: scroll;"></div>
                        </div>
                        <div class="col-lg-8" >
                            <form action="sendmessage" method="POST">
                                @csrf
                                <input type="hidden" name="user" value="{{ Auth::user()->name }}" >
                                <textarea class="form-control message"></textarea>
                                <br/>
                                <input type="button" value="Send" class="btn btn-success" id="send-message">
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<script>
    var socket = io.connect('http://localhost:8890');
    socket.on('message', function (data) {
        data = jQuery.parseJSON(data);
        $( "#messages" ).append( "<strong>"+data.user+":</strong><p>"+data.message+"</p>" );
    });
    $("#send-message").click(function(e){
        e.preventDefault();
        var _token = $("input[name='_token']").val();
        var user = $("input[name='user']").val();
        var message = $(".message").val();
        if(message != ''){
            $.ajax({
                type: "POST",
                url: '{!! URL::to("sendmessage") !!}',
                dataType: "json",
                data: {'_token':_token, 'message':message, 'user':user},
                success:function(data) {
                    $(".message").val('');
                }
            });
        }
    })
</script>
@endsection

Now we need to start node server. In Terminal go to the nodejs folder and run the command.

node server.js

And run Laravel application server using command.

php artisan serve

Now in your two different browser, go to the https://localhost:8000 and send message in the box.