0

I'm struggling with implementing Websocket on Laravel. I'm using laravel-echo-server on the server side. I have some notifications that I want to send with Websocket and then get on the client-side with Laravel echo.

I'll write down what I've done:

  • I've downloaded socket.io-client.js v2.3.1 and added <script src="{{ asset('path/socket.io.js') }}"></script> before <script src="{{ asset('path/app.js') }}"></script> in my blade file.
  • Configured Redis as queue connection and broadcast driver
  • Installed laravel-echo-server with npm install -g laravel-echo-server
  • Configured laravel-echo-server with laravel-echo-server init command. Configuration is:
{
    "authHost": "http://127.0.0.1:8000",
    "authEndpoint": "/broadcasting/auth",
    "clients": [
        {
            "appId": "9d98443b1518e747",
            "key": "7bd6ea5e93100621942c1a21093e4621"
        }
    ],
    "database": "redis",
    "databaseConfig": {
        "redis": {},
        "sqlite": {
            "databasePath": "/database/laravel-echo-server.sqlite"
        }
    },
    "devMode": true,
    "host": null,
    "port": "6006",
    "protocol": "http",
    "socketio": {},
    "secureOptions": 67108864,
    "sslCertPath": "",
    "sslKeyPath": "",
    "sslCertChainPath": "",
    "sslPassphrase": "",
    "subscribers": {
        "http": true,
        "redis": true
    },
    "apiOriginAllow": {
        "allowCors": true,
        "allowOrigin": "http://127.0.0.1:8000",
        "allowMethods": "GET, POST",
        "allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"
    }
}
  • Installed laravel echo with npm install --save laravel-echo
  • In bootstrap.js configured Echo like this:
import Echo from 'laravel-echo';


window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.Laravel.wsurl + ':6006',
    disableStats: true,
    enabledTransports: ['ws', 'wss'],
    transports: ['websocket', 'polling', 'flashsocket'],
    auth: {
        headers: {
            'Authorization': 'Bearer ' + window.Laravel.wskey,
            'X-CSRF-TOKEN': window.Laravel.csrfToken
        }
    }
});
  • I've run npm run dev to compile the code.
  • This is my notification class:
<?php

namespace Modules\Ticket\Notifications;

use App\Channels\SmsChannel;
use App\Channels\UserDatabaseChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\BroadcastMessage;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Queue\SerializesModels;
use Modules\Ticket\Entities\Ticket;
use Modules\Ticket\Jobs\AdminTicketCreatedSms;

class AdminTicketCreated extends Notification implements ShouldBroadcast, ShouldQueue
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public Ticket $ticket;
    private int $userId;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct(Ticket $ticket)
    {
        $this->userId = $ticket->user_id;
        $this->ticket = $ticket;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param mixed $notifiable
     * @return array
     */
    public function via($notifiable): array
    {
//        return [SmsChannel::class, 'mail', 'broadcast', UserDatabaseChannel::class];
        return ['broadcast', UserDatabaseChannel::class];
    }

    public function toMail($notifiable)
    {
        return (new MailMessage())
            ->subject('ارسال تیکت توسط ارزی لند')
            ->replyTo($notifiable->email, $notifiable->name)
            ->view('emails.ticket_send_admin', ['user' => $notifiable, 'ticket' => $this->ticket]);

    }

    public function toSms($notifiable)
    {
        dispatch(new AdminTicketCreatedSms($notifiable->user, $this->ticket))->delay(60);
    }

    public function toDatabase($notifiable)
    {
        return [
            'title' => "تیکت جدید ثبت شد",
            'url' => route('notification.show', ['id' => $this->id]),
        ];
    }

    public function toBroadcast()
    {
        return new BroadcastMessage([
            'title' => "تیکت جدید ثبت شد",
        ]);
    }

    public function broadcastOn()
    {
        return new PrivateChannel('App.User.' . $this->userId);
    }

}

As you see, I'm broadcasting the notification on 'App.User.userId' so in blade I have to be enabled to get it with something like this:

Echo.private('App.User.{{ auth()->id() }}').notification((response) => {
    console.log(response);
});

I have three terminals open with these commands:

  • php artisan serve
  • php artisan queue:listen --tries=1
  • laravel-echo-server start

Now, I have a problem: On the client-side laravel echo doesn't subscribe to the event! (I'm using a test route to trigger the notification and it's working in queue and laravel-echo-server console) laravel-echo-server console queue console

BTW, I'm using Windows 10 and Wampserver for development.

In addition, I've also enabled BroadcastServiceProvider and added this in channels.php:

Broadcast::channel('App.User.{id}', function ($user, $id) {
    return true; // this is for test, I have logic for this part
});

I'll be appreciated any help. :)

Ashkan
  • 47
  • 1
  • 8

0 Answers0