DEV Community

Midhun Manu
Midhun Manu

Posted on • Updated on

How to make a Chat App using Laravel 11 , Angular 17 and Web Sockets

Hello Developers I am Midhun and in this small blog I will show you how to create a simple real time chat app using Laravel 11and Angular 17.

Let's start with out Back End

  1. Create a Laravel project
    composer create-project laravel/laravel
    server

  2. php artisan install:api

  3. Install Broadcasting
    php artisan install:broadcasting

    since we are making a server - client application do no install Reverb

  4. Install Pusher
    composer require pusher/pusher-php-server

  5. In your .env add Pusher configs

    PUSHER_APP_ID="your-pusher-app-id"
    PUSHER_APP_KEY="your-pusher-key"
    PUSHER_APP_SECRET="your-pusher-secret"
    PUSHER_HOST=
    PUSHER_PORT=443
    PUSHER_SCHEME="https"
    PUSHER_APP_CLUSTER="mt1"

    ensure that you set your Broadcast Connection as pusher instead of logs in your .env

  6. Now we will make an event
    php artisan make event:ChatMessageEvent

  7. In our ChatMessageEvent

<?php

namespace App\Events;

use App\Models\Chat\Message;
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\SerializesModels;

class ChatMessageEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public Message $message;

    public function __construct($message)
    {
        $this->message = $message;
    }

    public function broadcastOn(): array
    {
        return [
            new Channel('chat'),
        ];
    }

    public function broadcastAs(): string
    {
        return 'message';
    }
}
Enter fullscreen mode Exit fullscreen mode

For our web sockets we need the ShouldBroadcast interface.
The BroadCastOn method gives the channel and
the BroadCastAs method gives the event.

  1. Create a Controller

php artisan make:controller ChatController

<?php

namespace App\Http\Controllers;

use App\Events\ChatMessageSent;
use App\Events\UserJoined;
use Illuminate\Http\Request;

class ChatController extends Controller
{
    public function sendMessage(Request $request)
    {
        $username = $request->input("username");
        $message = $request->input("message");

        event(new ChatMessageSent($username, $message));
        return response()->json(["status" => "Message Sent"], 200);
    }
}
Enter fullscreen mode Exit fullscreen mode
  1. Add the route in api.php

Route::post("/send", [ChatController::class, "sendMessage"]);

  1. Start the server

php artisan serve

  1. Run the queue php artisan queue:work

Let's Start the Angular Front End Now

  1. make an Angular App

ng new client --standalone false --strict false

  1. install pusher-js

npm i pusher-js

  1. create the components
ng g c chat
ng g c login
Enter fullscreen mode Exit fullscreen mode
  1. let's connect the client to sockets

in chat.component.ts

this is what we are going to use

this.pusherInstance = new Pusher("PUSHER_KEY", {
      cluster: "ap2"
    });

    this.channel = this.pusherInstance.subscribe("chat");
    this.channel.bind("message", (data:any) => {
      console.log(JSON.stringify(data))

    })

Enter fullscreen mode Exit fullscreen mode
  1. so this is how out chat component be:
import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import Pusher from 'pusher-js';
interface Message {
  username: string;
  message:string;
}

@Component({
  selector: 'app-chat',
  templateUrl: './chat.component.html',
  styleUrl: './chat.component.css'
})
export class ChatComponent implements OnInit {

  username = "username";
  message = "";
  messages: Message[] = [];
  users: string[] = [];
  pusherInstance:any;
  channel: any;
  currentUser = "";

  ngOnInit(): void {
    this.username = history.state.currentUser;
    this.users.push(this.username);
    this.pusherInstance = new Pusher("PUSHER_KEY", {
      cluster: "ap2"
    });

    this.channel = this.pusherInstance.subscribe("chat");
    this.channel.bind("message", (data:any) =>